在显示 CreateView 之前检查用户是否没有对象 - 防止多次创建
Check if user doesn't have object before displaying CreateView - Prevent multiple creation
过去几周我一直在慢慢学习Django,并将其应用到工作原型中。我有一个名为 Applicant 的简单个人资料模型。
- 这存储了客户的个人字段。
- 它包含一个 OnetoOne 字段 linking 到 Django Auth User 模型,因为我使用它来要求登录和控制对数据的访问。
我正在努力弄清楚如何在 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)
过去几周我一直在慢慢学习Django,并将其应用到工作原型中。我有一个名为 Applicant 的简单个人资料模型。
- 这存储了客户的个人字段。
- 它包含一个 OnetoOne 字段 linking 到 Django Auth User 模型,因为我使用它来要求登录和控制对数据的访问。
我正在努力弄清楚如何在 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)