主键作为 MultipleChoiceField 中的选项
Primary keys as choices in MultipleChoiceField
这件事对我来说很明显,但我仍然可以让它发挥作用。
之前我尝试通过覆盖 __init__
方法从 MultipleModelChoiceField
获取过滤后的模型实例,并且它按预期工作。现在我只需要从这些实例中获取 pk
,我决定在 MultipleChoiceField
中执行此操作。我尝试通过以下方式进行但没有成功:
class AnswerForm(forms.Form):
answers = forms.MultipleChoiceField(
choices = [answer.pk for answer in Answer.objects.all()],
widget = forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
q_pk = kwargs.pop('q_pk')
super(AnswerForm, self).__init__(*args, **kwargs)
self.fields['answers'].choices = [answer.pk for answer in Answer.objects.filter(question__pk=q_pk)]
简而言之:不要这样做,坚持 ModelMultipleChoiceField
。
这显然行不通,因为 choices 需要一个元组列表。考虑到这一点,[answer.pk for answer in Answer.objects.filter(question__pk=q_pk)]
可以重写为 Answer.objects.filter(question__pk=q_pk).values_list('pk', 'someotherfield')
,这让您回到 ModelMultipleChoiceField
的作用。
非常感谢 Ivan 指导我使用 ModelChoiceField。
这是我的疏忽,因为我现在才发现我还需要将一些其他模型字段(pk除外)传递给表单。
在那种情况下,我发现将模型主键作为所选输入的值的最佳方法是首先从表单中获取整个模型,然后迭代它们以获得所需的字段值如下:
forms.py
class AnswerForm(forms.Form):
answer = forms.ModelMultipleChoiceField(
queryset = Answer.objects.all(),
widget = forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
q_pk = kwargs.pop('q_pk', None)
super(AnswerForm, self).__init__(*args, **kwargs)
self.fields['answer'].queryset = Answer.objects.filter(question__pk=q_pk)
views.py
checked = [answer.pk for answer in form.cleaned_data['answer']]
这件事对我来说很明显,但我仍然可以让它发挥作用。
之前我尝试通过覆盖 __init__
方法从 MultipleModelChoiceField
获取过滤后的模型实例,并且它按预期工作。现在我只需要从这些实例中获取 pk
,我决定在 MultipleChoiceField
中执行此操作。我尝试通过以下方式进行但没有成功:
class AnswerForm(forms.Form):
answers = forms.MultipleChoiceField(
choices = [answer.pk for answer in Answer.objects.all()],
widget = forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
q_pk = kwargs.pop('q_pk')
super(AnswerForm, self).__init__(*args, **kwargs)
self.fields['answers'].choices = [answer.pk for answer in Answer.objects.filter(question__pk=q_pk)]
简而言之:不要这样做,坚持 ModelMultipleChoiceField
。
这显然行不通,因为 choices 需要一个元组列表。考虑到这一点,[answer.pk for answer in Answer.objects.filter(question__pk=q_pk)]
可以重写为 Answer.objects.filter(question__pk=q_pk).values_list('pk', 'someotherfield')
,这让您回到 ModelMultipleChoiceField
的作用。
非常感谢 Ivan 指导我使用 ModelChoiceField。 这是我的疏忽,因为我现在才发现我还需要将一些其他模型字段(pk除外)传递给表单。
在那种情况下,我发现将模型主键作为所选输入的值的最佳方法是首先从表单中获取整个模型,然后迭代它们以获得所需的字段值如下:
forms.py
class AnswerForm(forms.Form):
answer = forms.ModelMultipleChoiceField(
queryset = Answer.objects.all(),
widget = forms.CheckboxSelectMultiple,
)
def __init__(self, *args, **kwargs):
q_pk = kwargs.pop('q_pk', None)
super(AnswerForm, self).__init__(*args, **kwargs)
self.fields['answer'].queryset = Answer.objects.filter(question__pk=q_pk)
views.py
checked = [answer.pk for answer in form.cleaned_data['answer']]