Проверьте, нет ли у пользователя уже этого объекта, прежде чем отображать CreateView - Запретите ему создавать множественные объекты
Последние несколько недель я медленно изучаю Django и применяю его на рабочем прототипе. У меня есть простая модель профиля под названием Applicant. Она хранит персональные поля для клиента. Она содержит поле OnetoOne, связывающееся с моделью Django Auth User, поскольку я использую ее для требования входа и контроля доступа к данным. Я не могу понять, как выполнять проверки в классах View Classes (казалось бы, проще в функциях View Functions), мне нужен способ проверить, есть ли у пользователя уже запись Applicant, прежде чем представить ему форму CreateView.
Раньше для отображения данных профиля кандидата (созданного через страницу администратора) я использовал get_object_or_404 в DetailView.get_object, чтобы перехватить Http404 и вернуть None, если у него нет профиля. Это давало ссылку на страницу "Создать". Мне нужно реализовать обратную логику на CreateView, чтобы защитить их от создания нескольких записей о соискателях.
Любые предложения были бы замечательными, даже просто указать мне правильное направление.
Код, который я использовал для DetailView:
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
<h1>Applicant Profile</h1>
{% if applicant %}
...
{% else %}
<p>You have not created an Applicant profile, click below to create one.</p>
<a href="/profile/create" class="btn btn-primary"> Create Profile </a>
{% 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 %}
<p>You already have an Applicant profile. If you'd like to edit it, please use the edit option on the profile page.</p>
<a href="/profile/" class="btn btn-primary"> View Profile </a>
{% else %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% endif %}
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)