温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Django表单模型选择框怎么使用分组

发布时间:2021-02-05 13:45:55 来源:亿速云 阅读:228 作者:小新 栏目:开发技术

小编给大家分享一下Django表单模型选择框怎么使用分组,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

起步

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)

它能渲染出:

Django表单模型选择框怎么使用分组

使用分组下拉框

还可以使用如下方式生成 <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)

能够渲染为:

Django表单模型选择框怎么使用分组

分组模型下拉框

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

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

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

from django.db import models class Category(models.Model):   name = models.CharField(max_length=30)   parent = models.ForeignKey('Category', on_delete=models.CASCADE, null=True)   def __str__(self):     return self.name class 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 partial from itertools import groupby from operator import attrgetter from django.forms.models import ModelChoiceIterator, ModelChoiceField class 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 forms from .fields import GroupedModelChoiceField from .models import Category, Expense class ExpenseForm(forms.ModelForm):   category = GroupedModelChoiceField(     queryset=Category.objects.exclude(parent=None),      choices_groupby='parent'   )   class Meta:     model = Expense     fields = ('amount', 'date', 'category')

以上是“Django表单模型选择框怎么使用分组”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI