香港云主机最佳企业级服务商!

ADSL拨号VPS包含了中国大陆(联通,移动,电信,)

中国香港,国外拨号VPS。

当前位置:云主机 > python >

电信ADSL拨号VPS
联通ADSL拨号VPS
移动ADSL拨号VPS

Django 表单模型选择框如何使用分组


时间:2022-04-02 10:36 作者:admin


起步

Django 表单中有两种字段类型可以使用选择框: ChoiceFieldModelChoiceField

对于 ChoiceField 的基本使用是:

class ExpenseForm(forms.Form):  CHOICES = (    (11, 'Credit Card'),    (12, 'Student Loans'),    (13, 'Taxes'),    (21, 'Books'),    (22, 'Games'),    (31, 'Groceries'),    (32, 'Restaurants'),  )  date = forms.DateField()  category = forms.ChoiceField(choices=CHOICES)

它能渲染出:

使用分组下拉框

还可以使用如下方式生成 <optgourp> 标签:

class ExpenseForm(forms.Form):  CHOICES = (    ('Debt', (      (11, 'Credit Card'),      (12, 'Student Loans'),      (13, 'Taxes'),    )),    ('Entertainment', (      (21, 'Books'),      (22, 'Games'),    )),    ('Everyday', (      (31, 'Groceries'),      (32, 'Restaurants'),    )),  )  date = forms.DateField()  category = forms.ChoiceField(choices=CHOICES)

能够渲染为:

分组模型下拉框

如果使用的是 ModelChoiceField ,那抱歉,Django本身没有提供解决方案。

在 https://code.djangoproject.com/ticket/27331 中提供了一个很好的解决方案。

首先为需要分类的类型创建模型,在另一个模型中用外键关联它:

from django.db import modelsclass Category(models.Model):  name = models.CharField(max_length=30)  parent = models.ForeignKey('Category', on_delete=models.CASCADE, null=True)  def __str__(self):    return self.nameclass Expense(models.Model):  amount = models.DecimalField(max_digits=10, decimal_places=2)  date = models.DateField()  category = models.ForeignKey(Category, on_delete=models.CASCADE)  def __str__(self):    return self.amount

其次,创建一个新的表单 Field 类型:

from functools import partialfrom itertools import groupbyfrom operator import attrgetterfrom django.forms.models import ModelChoiceIterator, ModelChoiceFieldclass GroupedModelChoiceIterator(ModelChoiceIterator):  def __init__(self, field, groupby):    self.groupby = groupby    super().__init__(field)  def __iter__(self):    if self.field.empty_label is not None:      yield ("", self.field.empty_label)    queryset = self.queryset    # Can't use iterator() when queryset uses prefetch_related()    if not queryset._prefetch_related_lookups:      queryset = queryset.iterator()    for group, objs in groupby(queryset, self.groupby):      yield (group, [self.choice(obj) for obj in objs])class GroupedModelChoiceField(ModelChoiceField):  def __init__(self, *args, choices_groupby, **kwargs):    if isinstance(choices_groupby, str):      choices_groupby = attrgetter(choices_groupby)    elif not callable(choices_groupby):      raise TypeError('choices_groupby must either be a str or a callable accepting a single argument')    self.iterator = partial(GroupedModelChoiceIterator, groupby=choices_groupby)    super().__init__(*args, **kwargs)

最后,在表单中可以如下进行使用:

from django import formsfrom .fields import GroupedModelChoiceFieldfrom .models import Category, Expenseclass ExpenseForm(forms.ModelForm):  category = GroupedModelChoiceField(    queryset=Category.objects.exclude(parent=None),     choices_groupby='parent'  )  class Meta:    model = Expense    fields = ('amount', 'date', 'category')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

(责任编辑:admin)






帮助中心
会员注册
找回密码
新闻中心
快捷通道
域名登录面板
虚机登录面板
云主机登录面板
关于我们
关于我们
联系我们
联系方式

售前咨询:17830004266(重庆移动)

企业QQ:383546523

《中华人民共和国工业和信息化部》 编号:ICP备00012341号

Copyright © 2002 -2018 香港云主机 版权所有
声明:香港云主机品牌标志、品牌吉祥物均已注册商标,版权所有,窃用必究

云官方微信

在线客服

  • 企业QQ: 点击这里给我发消息
  • 技术支持:383546523

  • 公司总台电话:17830004266(重庆移动)
  • 售前咨询热线:17830004266(重庆移动)