我有一个具有ManyToMany关系的类,我想用它来为应用创建一个控制面板:
class ControlPanel(models.Model):
viewtype = models.CharField("view type", max_length=32, unique=True)
choice1 = models.ManyToManyField(Choice1, null=True)
choice2 = models.ManyToManyField(Choice2, null=True)
choice3 = models.ManyToManyField(Choice3, null=True)
其中Choice1
,Choice2
和Choice3
是我想要呈现为复选框的选项。 controlpanel_choice1
,controlpanel_choice2
和controlpanel_choice3
是与Choice1
,Choice2
和Choice3
选项相关的M2M关系表。因此,根据viewtype id,每个Choice*
集的选择集可能不同(甚至不存在)。
我从这个ControlPanel类创建了一个表单来生成我的控制面板:
class ControlPanelForm(ModelForm):
viewtype = forms.ChoiceField(choices = ControlPanel.objects.values_list('id','view'))
choice1 = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Choice1.objects.all())
choice2 = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Choice2.objects.all())
choice3 = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=Choice3.objects.all())
class Meta:
model = ControlPanel
这会显示3选项*字段。但是,它不会限制对每个viewtype选项的选择,因为我的查询集会为每个.objects.all()
字段显示choice*
。此外,这将显示对象地址,而不是每个Choice *的名称字段。
我怎样才能做到这一点?我需要为绑定和未绑定表单显示Choice *。我是否需要在构造函数中构建它们,检查我的表单是否有效并获取当前选定的viewtype来构建我的查询集?我可以在ControlPanel
类中使用此逻辑,并避免在我的视图函数中编程吗?我会很感激一些例子。
提前致谢。
答案 0 :(得分:0)
首先,您需要创建一个接受参数的表单
class ControlPanelForm(ModelForm):
class Meta:
model = ControlPanel
widgets = {
'choice1': forms.CheckboxSelectMultiple(),
'choice2': forms.CheckboxSelectMultiple(),
'choice3': forms.CheckboxSelectMultiple(),
}
def __init__(self, *args, **kwargs):
viewtype = kwargs.pop('viewtype')
super(ControlPanelForm, self).__init__(*args, **kwargs)
self.fields['choice1'].queryset = Choice1.objects.filter( ... )
self.fields['choice2'].queryset = Choice2.objects.filter( ... )
self.fields['choice3'].queryset = Choice3.objects.filter( ... )
正如您所看到的,我已将viewtype
作为位置参数传递给表单的init,现在您可以使用它来创建filter()
的查询集,而不是使用{{1 }}
此外,使用all()
时,无需再次声明表单字段。如果您需要更改任何字段的小部件,使用ModelForm
类的widgets
选项似乎更合适。
现在,要在您的视图中使用此表单,只需将Meta
作为位置参数传递。
viewtype
现在你要做的就是将它放在一个视图中,并在每次传入不同的viewtype = request.POST['viewtype']
form = ControlPanelForm(viewtype=viewtype)
时调用它。
答案 1 :(得分:0)
只是对这个问题的后续跟进:我意识到使用javascript / jQuery在客户端实现这种功能更合乎逻辑。实际上,由于HTM1的非持久性方面,在服务器端具有这样的逻辑是非常尴尬和容易出错的。我在学习基本的jQuery方面遇到了很多麻烦,并且有一种很好的方法可以在浏览器端隐藏/显示选项和结果。