我有一个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
我正在考虑这样一种情况,即这个初始查询不返回任何结果。下面的方法会产生错误,最终表单将不会呈现,这将是一个相当大的灾难!
因此,我需要以某种方式打破这一流程,并提供一条类似于“对不起没有发现任何东西”的消息。
正如您所看到的,我目前有if not initial_queryset: raise Http404()
,但是我对这个解决方案并不满意,因为从技术上讲,它不是一个“未找到的页面”,需要为这个场景提供一个自定义消息。
我倾向于将用户重定向到另一个视图,并呈现一条带有链接的消息,以返回、编辑他们的搜索(例如)。
我尝试过返回HttpResponseRedirect()
,但这只是将响应对象分配给调用函数的变量!
有什么更好的办法来解决这个问题吗?
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)
发布于 2020-12-16 14:42:03
在进入表单逻辑之前,我将重写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)
正如您已经发现的,重定向不允许您自定义消息。如果设置为重定向,则可以重定向到另一个通过相同逻辑确定旅行不可用的视图,然后显示一条消息。您可能会将一些常见的函数提取到视图混合器中。
https://stackoverflow.com/questions/65331387
复制相似问题