从函数调用(Django FormView)中提升 Http404 的替代方案?
Alternative to raising Http404 from within a function call, (Django FormView)?
我有一个 FormView,它在模板中呈现一个 ModelForm。该表单包括基于动态查询集的 ModelChoiceField,该查询集在初始化表单时传入 kwargs(请参阅下面视图的完整代码)
def get_form_kwargs(self, **kwargs):
""" Provides keyword arguemnt """
kwargs = super(NameofView, self).get_form_kwargs()
queryset = self.my_custom_method(self.param1, self.param2)
kwargs.update({"queryset": queryset})
return kwargs
此查询集由初始数据库查询使用会话中的值确定,并进一步过滤。在到达上述方法之前,有很多方法在起作用,因此在 request.POST 和 request.GET.
中形成相同的查询集
具体我调用一个方法:
def get_initial_queryset(self, session_variable1, session_variable2):
initial_queryset = Model.objects.filter(
attr1=session_variable1
).filter(
attr2__gte=session_variable2)
if not initial_queryset:
raise Http404("Sorry, none available")
return initial_queryset
我正在考虑初始查询 returns 没有结果的情况。接下来的方法会报错,最终表单无法渲染,那将是一场灾难!!
因此,我需要以某种方式打破流程,而不是呈现一条类似于 'Sorry nothing was found'.
的消息
如您所见,我目前有 if not initial_queryset: raise Http404()
但我对这个解决方案不满意,因为从技术上讲它不是 'page not found' 并且需要针对此场景的自定义消息。
我更愿意将用户重定向到另一个视图并呈现一条消息,其中包含链接以返回编辑他们的搜索(例如。)
我已经尝试返回 HttpResponseRedirect()
,但这只是将 Response 对象分配给调用该函数的变量!
有没有更好的方法来实现这个目标?
class NameofView(FormView):
model = Model
template_name = "app/template.html"
form_class = RefineSelectionForm
def get_initial_queryset(self, session_variable1, session_variable2):
initial_queryset = Model.objects.filter(
attr1=session_var1
).filter(
attr2__gte=session_var2)
if not initial_queryset:
raise Http404("Sorry, none available")
return initial_queryset
def refine_queryset1(self, session_var1, session_var2, session_var3):
initial_queryset = self.get_initial_queryset(session_var1, session_var2)
refined_qs1 = initial_queryset.filter(session_var1__gte=session_var1)[:3]
return refined_qs1
def refine_queryset2(self, self, session_var1, session_var2, session_var3):
initial_queryset = self.get_intitial_queryset(session_var1, session_var2)
refined_qs2 = initial_queryset.filter(attr__lt=date).order_by("-date")[:3]
return refined_qs2
def my_custom_method(self, param1, param2):
"""Creates the queryset that will be used by the ModelChoiceField
in the Form"""
# Merge both queries
queryset = param1 | param2
return queryset
def get_initial(self):
# Retrieve values from the session
session_variable1 = self.request.session["session_variable1"]
self.session_variable2 = self.request.session["session_variable2"]
self.session_variable3 = self.request.session["session_variable3"]
..comparisons etc...
if condition:
initial_data = initial_data1
else:
initial_data = initial_data2
initial = super(NameofView, self).get_initial()
initial.update({"formfield": initial_data})
return initial
def get_form_kwargs(self, **kwargs):
kwargs = super(NameofView, self).get_form_kwargs()
queryset = self.my_custom_method(self.param1, self.param2)
kwargs.update({"queryset": queryset})
return kwargs
def get_context_data(self, **kwargs):
context = super(NameofView, self).get_context_data(**kwargs)
queryobject = Model.objects.filter(pk=self.session_variable1)
context["some_data"] = self.session_variable2
context["some_object"] = queryobject
return context
def form_valid(self, form):
...code...
return redirect("named_path", args)
我会覆盖 get
函数来执行基本验证,甚至在进入表单逻辑之前。
from django.shortcuts import render
def get(self, request, *args, **kwargs)
if not self.get_available_trips().exists():
return render(request, "some_unavailable_template", context={"message": "your message"})
return super().get(request, *args, **kwargs)
如您所知,重定向不允许您自定义消息。如果您设置了重定向,则可以重定向到另一个视图,该视图通过相同的逻辑来确定行程不可用的原因,然后显示一条消息。您可能可以将一些常用函数提取到视图混合中。
我有一个 FormView,它在模板中呈现一个 ModelForm。该表单包括基于动态查询集的 ModelChoiceField,该查询集在初始化表单时传入 kwargs(请参阅下面视图的完整代码)
def get_form_kwargs(self, **kwargs):
""" Provides keyword arguemnt """
kwargs = super(NameofView, self).get_form_kwargs()
queryset = self.my_custom_method(self.param1, self.param2)
kwargs.update({"queryset": queryset})
return kwargs
此查询集由初始数据库查询使用会话中的值确定,并进一步过滤。在到达上述方法之前,有很多方法在起作用,因此在 request.POST 和 request.GET.
中形成相同的查询集具体我调用一个方法:
def get_initial_queryset(self, session_variable1, session_variable2):
initial_queryset = Model.objects.filter(
attr1=session_variable1
).filter(
attr2__gte=session_variable2)
if not initial_queryset:
raise Http404("Sorry, none available")
return initial_queryset
我正在考虑初始查询 returns 没有结果的情况。接下来的方法会报错,最终表单无法渲染,那将是一场灾难!!
因此,我需要以某种方式打破流程,而不是呈现一条类似于 'Sorry nothing was found'.
的消息如您所见,我目前有 if not initial_queryset: raise Http404()
但我对这个解决方案不满意,因为从技术上讲它不是 'page not found' 并且需要针对此场景的自定义消息。
我更愿意将用户重定向到另一个视图并呈现一条消息,其中包含链接以返回编辑他们的搜索(例如。)
我已经尝试返回 HttpResponseRedirect()
,但这只是将 Response 对象分配给调用该函数的变量!
有没有更好的方法来实现这个目标?
class NameofView(FormView):
model = Model
template_name = "app/template.html"
form_class = RefineSelectionForm
def get_initial_queryset(self, session_variable1, session_variable2):
initial_queryset = Model.objects.filter(
attr1=session_var1
).filter(
attr2__gte=session_var2)
if not initial_queryset:
raise Http404("Sorry, none available")
return initial_queryset
def refine_queryset1(self, session_var1, session_var2, session_var3):
initial_queryset = self.get_initial_queryset(session_var1, session_var2)
refined_qs1 = initial_queryset.filter(session_var1__gte=session_var1)[:3]
return refined_qs1
def refine_queryset2(self, self, session_var1, session_var2, session_var3):
initial_queryset = self.get_intitial_queryset(session_var1, session_var2)
refined_qs2 = initial_queryset.filter(attr__lt=date).order_by("-date")[:3]
return refined_qs2
def my_custom_method(self, param1, param2):
"""Creates the queryset that will be used by the ModelChoiceField
in the Form"""
# Merge both queries
queryset = param1 | param2
return queryset
def get_initial(self):
# Retrieve values from the session
session_variable1 = self.request.session["session_variable1"]
self.session_variable2 = self.request.session["session_variable2"]
self.session_variable3 = self.request.session["session_variable3"]
..comparisons etc...
if condition:
initial_data = initial_data1
else:
initial_data = initial_data2
initial = super(NameofView, self).get_initial()
initial.update({"formfield": initial_data})
return initial
def get_form_kwargs(self, **kwargs):
kwargs = super(NameofView, self).get_form_kwargs()
queryset = self.my_custom_method(self.param1, self.param2)
kwargs.update({"queryset": queryset})
return kwargs
def get_context_data(self, **kwargs):
context = super(NameofView, self).get_context_data(**kwargs)
queryobject = Model.objects.filter(pk=self.session_variable1)
context["some_data"] = self.session_variable2
context["some_object"] = queryobject
return context
def form_valid(self, form):
...code...
return redirect("named_path", args)
我会覆盖 get
函数来执行基本验证,甚至在进入表单逻辑之前。
from django.shortcuts import render
def get(self, request, *args, **kwargs)
if not self.get_available_trips().exists():
return render(request, "some_unavailable_template", context={"message": "your message"})
return super().get(request, *args, **kwargs)
如您所知,重定向不允许您自定义消息。如果您设置了重定向,则可以重定向到另一个视图,该视图通过相同的逻辑来确定行程不可用的原因,然后显示一条消息。您可能可以将一些常用函数提取到视图混合中。