在显示 CreateView 之前检查用户是否没有对象 - 防止多次创建

Check if user doesn't have object before displaying CreateView - Prevent multiple creation

过去几周我一直在慢慢学习Django,并将其应用到工作原型中。我有一个名为 Applicant 的简单个人资料模型。

我正在努力弄清楚如何在 View 类 中执行检查(在 View Functions 中似乎更容易)。

因此,我需要一种方法来检查用户是否已经有申请人条目,然后再向他们展示 CreateView 表单。

之前为了显示此申请人个人资料数据(通过管理页面创建),我在 DetailView.get_object 中使用 get_object_or_404 来捕获 Http404 和 return None 如果他们没有个人资料。

这将为“创建”页面提供 link。我需要在 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)