从查询集创建 Django 表单
Creating Django Forms from Querysets
我正在开发一个 Django 表单,让您可以订购海关比萨饼。例如,在将表单构建为 "Select Size" 时,我想从一个数据库中提取菜单项的可用尺寸,这样如果菜单发生变化,表单将自动知道可用的尺寸。
现在我对查询集显示时的返回方式有疑问。
我应该如何修改代码使得
queryset=query_list.values_list('size').distinct()
在下拉列表中显示为:小、中
而不是:(小,),(中,)
或者有没有办法直接从 class 中的 SIZE_CHOICES 元组中提取?
谢谢!
Models.py:
class Pizza(MenuItem):
STYLE_CHOICES = (
('Regular', 'Regular'),
('Sicilian', 'Sicilian'),
)
SIZE_CHOICES = (
('Small', 'Small'),
('Large', 'Large'),
)
style = models.CharField(max_length=16, blank=False, choices=STYLE_CHOICES)
size = models.CharField(max_length=16, blank=False, choices=SIZE_CHOICES)
num_toppings = models.IntegerField()
toppings = models.ManyToManyField(Topping, blank=True)
is_special = models.BooleanField(default=False)
def toppings_list(self):
return "\n".join([p.name for p in self.toppings.all()])
def __str__(self):
return f"{self.style} {self.size}"
forms.py
class PizzaForm(forms.Form):
query_list = Pizza.objects.all()
style = forms.ModelChoiceField(
widget=forms.Select,
queryset=query_list,
empty_label="Select Size"
)
size_choices = forms.ModelChoiceField(
widget=forms.Select,
queryset=query_list.values_list('size').distinct(),
empty_label="Select Size"
)
topping_choices = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Topping.objects.all(),
required=False
)
这不是 ModelChoiceField
[Django-doc], since you do not select a model object, but a value. You thus can use a ChoiceField
[Django-doc],并从模型中导入选择:
class PizzaForm(forms.Form):
style = <b>forms.ChoiceField</b>(
widget=forms.Select,
<b>choices=Pizza.STYLE_CHOICES</b>,
empty_label="Select Size"
)
size_choices = <b>forms.ChoiceField</b>(
widget=forms.Select,
<b>choices=Pizza.SIZE_CHOICES</b>,
empty_label="Select Size"
)
topping_choices = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Topping.objects.all(),
required=False
)
话虽这么说,您可能想查看 ModelForm
[Django-doc]。这可以自动构建基于模型的表单,并且进一步删除大量样板代码到save/update一个Pizza
数据库中的对象。
任何希望为非 ModelForm 创建选择字段的人,其中选择动态来自查询集但不是模型实例,您可以将可调用项传递给 [=12= 上的 choices
参数]
def _make_choices():
return [(c, c) for c in queryset.values_list('field', flat=True)]
choice_field = forms.ChoiceField(choices=_make_choices)
Willem 说,ModelForm 是解决这个问题的方法。
我正在开发一个 Django 表单,让您可以订购海关比萨饼。例如,在将表单构建为 "Select Size" 时,我想从一个数据库中提取菜单项的可用尺寸,这样如果菜单发生变化,表单将自动知道可用的尺寸。
现在我对查询集显示时的返回方式有疑问。
我应该如何修改代码使得
queryset=query_list.values_list('size').distinct()
在下拉列表中显示为:小、中
而不是:(小,),(中,)
或者有没有办法直接从 class 中的 SIZE_CHOICES 元组中提取?
谢谢!
Models.py:
class Pizza(MenuItem):
STYLE_CHOICES = (
('Regular', 'Regular'),
('Sicilian', 'Sicilian'),
)
SIZE_CHOICES = (
('Small', 'Small'),
('Large', 'Large'),
)
style = models.CharField(max_length=16, blank=False, choices=STYLE_CHOICES)
size = models.CharField(max_length=16, blank=False, choices=SIZE_CHOICES)
num_toppings = models.IntegerField()
toppings = models.ManyToManyField(Topping, blank=True)
is_special = models.BooleanField(default=False)
def toppings_list(self):
return "\n".join([p.name for p in self.toppings.all()])
def __str__(self):
return f"{self.style} {self.size}"
forms.py
class PizzaForm(forms.Form):
query_list = Pizza.objects.all()
style = forms.ModelChoiceField(
widget=forms.Select,
queryset=query_list,
empty_label="Select Size"
)
size_choices = forms.ModelChoiceField(
widget=forms.Select,
queryset=query_list.values_list('size').distinct(),
empty_label="Select Size"
)
topping_choices = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Topping.objects.all(),
required=False
)
这不是 ModelChoiceField
[Django-doc], since you do not select a model object, but a value. You thus can use a ChoiceField
[Django-doc],并从模型中导入选择:
class PizzaForm(forms.Form):
style = <b>forms.ChoiceField</b>(
widget=forms.Select,
<b>choices=Pizza.STYLE_CHOICES</b>,
empty_label="Select Size"
)
size_choices = <b>forms.ChoiceField</b>(
widget=forms.Select,
<b>choices=Pizza.SIZE_CHOICES</b>,
empty_label="Select Size"
)
topping_choices = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple,
queryset=Topping.objects.all(),
required=False
)
话虽这么说,您可能想查看 ModelForm
[Django-doc]。这可以自动构建基于模型的表单,并且进一步删除大量样板代码到save/update一个Pizza
数据库中的对象。
任何希望为非 ModelForm 创建选择字段的人,其中选择动态来自查询集但不是模型实例,您可以将可调用项传递给 [=12= 上的 choices
参数]
def _make_choices():
return [(c, c) for c in queryset.values_list('field', flat=True)]
choice_field = forms.ChoiceField(choices=_make_choices)
Willem 说,ModelForm 是解决这个问题的方法。