Проверьте, нет ли у пользователя уже этого объекта, прежде чем отображать 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)
Вернуться на верх