构造函数中的 Django ModelMultipleChoiceField 更新查询集在 POST 上失败
Posted
技术标签:
【中文标题】构造函数中的 Django ModelMultipleChoiceField 更新查询集在 POST 上失败【英文标题】:Django ModelMultipleChoiceField update queryset within constructor fails on POST 【发布时间】:2011-06-05 08:38:43 【问题描述】:我一直在回答 *** 上的各种问题,试图弄清楚如何在表单中使用 ModelMultipleChoiceFields。我几乎有一个工作表格,允许用户选择将文章翻译成的语言。我创建了一个表单,它采用SourceArticle
作为第一个构造函数参数,并使用它来指定我表单的languages
字段的查询集。
class AddTargetLanguagesForm(forms.Form):
def __init__(self, article=None, *args, **kwargs):
super(AddTargetLanguagesForm, self).__init__(*args, **kwargs)
self.fields['languages'].queryset = Language.objects.exclude(
Q(id = article.language.id) |
Q(id__in=[o.id for o in article.get_target_languages()]) |
Q(code="templates"))
languages = forms.ModelMultipleChoiceField(_("Languages"))
请注意,我的AddTargetLanguagesForm
不是基于ModelForm
,因为它与我的任何模型对象都没有直接关系。
当我第一次呈现表单时,它正确地为我提供了 (a) 不是源语言、(b) 尚未选择以及 (c) 不是特殊“模板”的语言“ 语言。但是,当我尝试发布表单时,出现以下错误:
AttributeError: 'QueryDict' 对象有 没有属性“语言”
我认为这与表单在 Django 中的工作方式有关,但我还是个新手。而不是接受SourceArticle
作为我的构造函数中的第一个参数,而是放置QueryDict
。我假设这包含来自请求的 POST 参数。我需要如何修改我的代码以使其能够捕获选定的语言?
这是我的观点的副本,如果它可以帮助您了解我是如何使用表单的。
@login_required
def add_target_languages(request, aid, template_name="wt_articles/add_target_languages.html"):
"""
Adds one or more target language translations to a source article.
"""
content_dict =
# Fetch the article
no_match = False
sa_set = SourceArticle.objects.filter(id=aid)
if len(sa_set) < 1:
no_match = True
content_dict['no_match'] = no_match
else:
article = sa_set[0]
content_dict['article'] = article
if request.method == "POST":
target_language_form = AddTargetLanguagesForm(request.POST)
if target_language_form.is_valid():
languages = target_language_form.cleaned_data['languages']
article.add_target_languages(languages)
return HttpResponseRedirect('/articles/list')
else:
target_language_form = AddTargetLanguagesForm(article)
content_dict['target_language_form'] = target_language_form
return render_to_response(template_name, content_dict,
context_instance=RequestContext(request))
【问题讨论】:
【参考方案1】:这一行是你的问题:
target_language_form = AddTargetLanguagesForm(request.POST)
这是从 POST 实例化表单的标准方法,但问题是您重写了 AddTargetLanguagesForm.__init__
的方法签名:
def __init__(self, article=None, *args, **kwargs):
所以第一个位置参数(在自动self
之后)是article
。您可以更改实例化,但我更喜欢这样做:
def __init__(self, *args, **kwargs):
article = kwargs.pop('article', None)
super(AddTargetLanguagesForm, self).__init__(*args, **kwargs)
if article is not None:
...etc...
【讨论】:
感谢您的帮助。我决定更改以保留AddTargetLanguagesForm.__init__
的签名并像这样传递article
值:target_language_form = AddTargetLanguagesForm(article, request.POST)
。我曾尝试使用kwargs.pop
,但由于这些更改,在呈现我的表单时出现错误。我最终没有进一步排除故障,而是更改了方法签名。以上是关于构造函数中的 Django ModelMultipleChoiceField 更新查询集在 POST 上失败的主要内容,如果未能解决你的问题,请参考以下文章