Django:在 Mixins Class 视图中验证受限制的外键形式
Django: validation of restricted Foreign keys forms in Mixins Class views
上下文:我如何处理 GET
上的外键限制
我在验证这个 form
时遇到了一些问题:
class RecordConsultationForm(forms.ModelForm):
class Meta:
model = Consultation
fields = ["fk_type", "fk_client", "duration", "date"]
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(RecordConsultationForm, self).__init__(*args, **kwargs)
self.fields['fk_client'].queryset = Client.objects.filter(fk_owner=self.user) # <=====HERE
queryset
将可用的 客户端 限制为 用户 。非常有效,我只需将以下内容添加到 get_context_data()
:
@method_decorator(login_required, name='dispatch')
class BrowseConsultations(BrowseAndCreate):
template_name = "console/browse_consultations.html"
model = Consultation
form_class = RecordConsultationForm
success_url = 'browse_consultations'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.form_class(user = self.request.user) #<=====HERE
return context
def post(self, request):
form = self.form_class(user = self.request.user) #<=====HERE
return super().post(request)
BrowseConsultations
上的表单验证
尽管我在 get_context_data()
和 post()
中添加了内容,但 POST
上的表单数据似乎无效,就好像用户是 None
(看起来是这样):
Invalid fk_client: Select a valid choice. 2 is not one of the available choices.
也许 get_context_data()
不是设置用户的正确位置?有什么办法可以调整 post()
中的 形式 吗?这是正确的方法吗?
其他详细信息
BrowseAndCreate
BrowseConsultations
继承自是我创建的 Mixing class 来处理常见的订购任务和消息。这是其中的一部分:
@method_decorator(login_required, name='dispatch')
class BrowseAndCreate(CreateView, TemplateView):
"""display a bunch of items from a model and the form to create new instances"""
def post(self, request):
super().post(request)
return redirect(self.success_url)
def form_valid(self, form):
super().form_valid(form)
messages.add_message(self.request, messages.SUCCESS,
"Recorded in {}".format(self.object.status))
def form_invalid(self, form):
for e in form.errors.items():
messages.add_message(self.request, messages.WARNING,
"Invalid {}: {}".format(e[0], e[1][0]))
环境
- django 3.0.4
- python 3.7
首先,CreateView
(您的 BrowseAndCreate
继承自)在 post 方法中处理表单验证,它在成功时调用 form_valid
form_invalid
失败。这两种方法都应该 return 一个 HTTP 响应。
此外,您覆盖的 FormMixin
中的 get_context_data
已经负责获取表单数据。
如果您需要在您的表单中使用 user
,您可以在您的表单中添加:
class RecordConsultationForm(forms.Form):
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
在您看来:
class BrowseConsultations(BrowseAndCreate):
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
上下文:我如何处理 GET
上的外键限制
我在验证这个 form
时遇到了一些问题:
class RecordConsultationForm(forms.ModelForm):
class Meta:
model = Consultation
fields = ["fk_type", "fk_client", "duration", "date"]
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(RecordConsultationForm, self).__init__(*args, **kwargs)
self.fields['fk_client'].queryset = Client.objects.filter(fk_owner=self.user) # <=====HERE
queryset
将可用的 客户端 限制为 用户 。非常有效,我只需将以下内容添加到 get_context_data()
:
@method_decorator(login_required, name='dispatch')
class BrowseConsultations(BrowseAndCreate):
template_name = "console/browse_consultations.html"
model = Consultation
form_class = RecordConsultationForm
success_url = 'browse_consultations'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.form_class(user = self.request.user) #<=====HERE
return context
def post(self, request):
form = self.form_class(user = self.request.user) #<=====HERE
return super().post(request)
BrowseConsultations
上的表单验证
尽管我在 get_context_data()
和 post()
中添加了内容,但 POST
上的表单数据似乎无效,就好像用户是 None
(看起来是这样):
Invalid fk_client: Select a valid choice. 2 is not one of the available choices.
也许 get_context_data()
不是设置用户的正确位置?有什么办法可以调整 post()
中的 形式 吗?这是正确的方法吗?
其他详细信息
BrowseAndCreate
BrowseConsultations
继承自是我创建的 Mixing class 来处理常见的订购任务和消息。这是其中的一部分:
@method_decorator(login_required, name='dispatch')
class BrowseAndCreate(CreateView, TemplateView):
"""display a bunch of items from a model and the form to create new instances"""
def post(self, request):
super().post(request)
return redirect(self.success_url)
def form_valid(self, form):
super().form_valid(form)
messages.add_message(self.request, messages.SUCCESS,
"Recorded in {}".format(self.object.status))
def form_invalid(self, form):
for e in form.errors.items():
messages.add_message(self.request, messages.WARNING,
"Invalid {}: {}".format(e[0], e[1][0]))
环境
- django 3.0.4
- python 3.7
首先,CreateView
(您的 BrowseAndCreate
继承自)在 post 方法中处理表单验证,它在成功时调用 form_valid
form_invalid
失败。这两种方法都应该 return 一个 HTTP 响应。
此外,您覆盖的 FormMixin
中的 get_context_data
已经负责获取表单数据。
如果您需要在您的表单中使用 user
,您可以在您的表单中添加:
class RecordConsultationForm(forms.Form):
def __init__(self, user, *args, **kwargs):
self.user = user
super().__init__(*args, **kwargs)
在您看来:
class BrowseConsultations(BrowseAndCreate):
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs