Проверьте, нет ли у пользователя объекта перед отображением CreateView — Предотвращение многократного создания

#django #django-views

#джанго #джанго-просмотры

Вопрос:

Последние несколько недель я медленно изучал Django и применял его к рабочему прототипу. У меня есть простая модель профиля под названием Кандидат.

  • Здесь хранятся личные поля для клиента.
  • Он содержит поле OneToOne, связанное с моделью пользователя Django Auth, так как я использую его, чтобы требовать входа в систему и контролировать доступ к данным.

Я изо всех сил пытаюсь понять, как выполнять проверки в классах представлений (казалось, проще в функциях представления).

Поэтому мне нужен способ проверить, есть ли у пользователя уже запись кандидата, прежде чем предоставлять им форму CreateView.

Ранее для отображения данных профиля кандидата (созданных на странице администратора) я использовал get_object_or_404 в DetailView.get_object, чтобы перехватить Http404 и не возвращать, если у них не было профиля.

Затем будет предоставлена ссылка на страницу создания. Мне нужно реализовать обратную логику в CreateView, чтобы защитить их от создания нескольких записей кандидатов.

Любые предложения были бы великолепны, даже просто для того, чтобы указать мне правильное направление.

Код, который я использовал для просмотра деталей:

 class ApplicantProfileDetailView(LoginRequiredMixin, generic.DetailView):  model = Applicant  template_name ='profile.html'  def get_object(self, queryset=None):  try:  return get_object_or_404(Applicant, user=self.request.user)  except Http404:  return None   
 lt;h1gt;Applicant Profilelt;/h1gt; {% if applicant %}  ... {% else %}  lt;pgt;You have not created an Applicant profile, click below to create one.lt;/pgt;  lt;a href="/profile/create" class="btn btn-primary"gt; Create Profile lt;/agt; {% endif %}  

Попытка реализовать то же самое в CreateView просто отобразит форму, несмотря ни на что:

 class ApplicantProfileCreateView(LoginRequiredMixin, generic.CreateView):  model = Applicant  fields = [...]  template_name = 'profile_create_form.html'  success_url = '/'  def get_object(self, queryset=None):  try:  return get_object_or_404(Applicant, user=self.request.user)  except Http404:  return None  
 {% if applicant %}  lt;pgt;You already have an Applicant profile. If you'd like to edit it, please use the edit option on the profile page.lt;/pgt;  lt;a href="/profile/" class="btn btn-primary"gt; View Profile lt;/agt; {% else %}  lt;form method="post"gt;  {% csrf_token %}  {{ form.as_p }}  lt;input type="submit" value="Save"gt;  lt;/formgt; {% endif %}  

Ответ №1:

generic.CreateView не определяет get_object метод, поэтому ваша проверка авторизации никогда не выполняется. Вы могли бы поместить его в get функцию, хотя, предположительно, пользователю потребуется запросить страницу перед отправкой на нее (если только это не представление ajax).

 class ApplicantProfileCreateView(LoginRequiredMixin, generic.CreateView):  model = Applicant  fields = [...]  template_name = 'profile_create_form.html'  success_url = '/'   def get(self, request, *args, **kwargs):  if Application.objects.filter(user=self.request.user).exists():  return redirect('/profile/') # ideally you'd use the url name here instead.  return super().get(request, *args, **kwargs)  

Комментарии:

1. Легенда! Это отлично работает, и я тоже могу очистить свой сомнительный обзор деталей. Спасибо за быстрый ответ.