Django中的一个常见需求是从查询集中填充一个表单的ChoiceField字段,并将选择与模型对象关联起来。

25
我有一个简单的表单:
class SubmissionQuickReplyForm(forms.Form):
    comment_text = forms.CharField(label='', required=False, widget=forms.Textarea(attrs={'rows':2}))

我想在表单中添加一个form.ChoiceField,其中ChoiceField中的选项是从一个查询集中获取的。
class SubmissionQuickReplyForm(forms.Form):
        comment_text = forms.CharField(label='', required=False, widget=forms.Textarea(attrs={'rows':2}))
        choice = forms.ChoiceField(...)

例如,如果我有:
q = MyChoices.Objects.all()

如何将ChoiceField填充为q的内容,以便在处理表单结果时,我可以在最后取回该对象?
    if request.method == "POST":
        form = SubmissionQuickReplyForm(request.POST)
        if form.is_valid():
            ch = get_object_or_404(MyChoices, pk=?)
            # How do I get my object from the choice form field?
2个回答

66
您可以使用 ModelChoiceField 代替。
choice = forms.ModelChoiceField(queryset=MyChoices.objects.all())

只需像这样简单地调用cleaned_data即可。

if request.method == "POST":
    form = SubmissionQuickReplyForm(request.POST)
    if form.is_valid():
        ch = form.cleaned_data.get('choice')

2
应该是 mychoices.objects.all() - objects 全部小写 :) - Thaian

13
对于ChoiceField,您可以使用
choice = forms.ChoiceField(
    choices=[(choice.pk, choice) for choice in MyChoices.objects.all()]
)

在表单的init方法中使用它。
class SubmissionQuickReplyForm(forms.Form):
    comment_text = forms.CharField(
        label='', required=False, widget=forms.Textarea(attrs={'rows':2})
    )
    choice = forms.ChoiceField()

    def __init__(self, *args, **kwargs):
         super(SubmissionQuickReplyForm, self).__init__(*args, **kwargs)

         self.fields['choice'].choices = [
             (choice.pk, choice) for choice in MyChoices.objects.all()
         ]

11
不要这样做 - 这只会在模块被加载时评估,这意味着选项不会随数据变化而更新。 - Adam Bard
ChoiceField没有查询集,因此它是填充choiceField的一种方式。@AdamBard - Dimitris Kougioumtzis
@DimitrisKougioumtzis 他试图表达的是在 Django 启动时将进行评估,因此选择将保持静态,直到服务器重新启动。你应该在 __init__ 方法中进行这样的操作。 - Sam Morgan
@SamMorgan 好的,我更新了我的回答。 - Dimitris Kougioumtzis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接