我想创建一个查询集,其中当前用户用作ModelForm中的过滤器:
class BookSubmitForm(ModelForm):
book = forms.ModelChoiceField(queryset=Book.objects.filter(owner=request.user),)
...
Run Code Online (Sandbox Code Playgroud)
Django是否将请求传递给表单?这是好习惯吗?我该如何使用该请求?(当然没有定义名称请求)
编辑:
我尝试了另一个解决方案,即在视图中调用表单传递请求:
form = BookSubmitForm(request)
Run Code Online (Sandbox Code Playgroud)
然后在我使用的形式:
class BookSubmitForm(ModelForm):
def __init__(self, request, *args, **kwargs):
super(BookSubmitForm, self).__init__(*args, **kwargs)
self.fields["library"].queryset = Library.objects.filter(owner=request.user)
Run Code Online (Sandbox Code Playgroud)
它工作,代码在表单中.现在我不确定它是最好的解决方案,它可以改进吗?
Ada*_*mKG 35
不,请求不会传递给ModelForm.您需要在视图中执行以下操作:
form = BookSubmitForm()
form.fields['book'].queryset = Book.objects.filter(owner=request.user)
# pass form to template, etc
Run Code Online (Sandbox Code Playgroud)
正如你所说,这是经常清洁的Form对象中封装这个,特别是如果你有几个领域将需要过滤的查询集.要做到这一点,覆盖表单__init__()并让它接受一个kwarg request:
class BookSubmitForm(ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super(BookSubmitForm, self).__init__(*args, **kwargs)
self.fields["book"].queryset = Book.objects.filter(owner=self.request.user)
self.fields["whatever"].queryset = WhateverModel.objects.filter(user=self.request.user)
Run Code Online (Sandbox Code Playgroud)
然后只要BookSubmitForm在视图中实例化时传递请求:
def book_submit(request):
if request.method == "POST":
form = BookSubmitForm(request.POST, request=request)
# do whatever
else:
form = BookSubmitForm(request=request)
# render form, etc
Run Code Online (Sandbox Code Playgroud)
将AdamKG答案扩展到基于类的视图-覆盖get_form_kwargs方法:
class PassRequestToFormViewMixin:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
from django.views.generic.edit import CreateView
class BookSubmitCreateView(PassRequestToFormViewMixin, CreateView):
form_class = BookSubmitForm
# same for EditView
Run Code Online (Sandbox Code Playgroud)
然后是以下形式:
from django.forms import ModelForm
class BookSubmitForm(ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request")
super().__init__(*args, **kwargs)
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13079 次 |
| 最近记录: |