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

 更新时间:2019年05月16日 08:21:28   作者:栖迟於一丘  
这篇文章主要介绍了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)

它能渲染出:

使用分组下拉框

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

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

相关文章

  • Python的字符串操作简单实例

    Python的字符串操作简单实例

    这篇文章主要介绍了Python的字符串操作简单实例,字符串有许多种操作方式,本文带来几个操作实例,快来一起看看吧
    2023-04-04
  • 用Python编写脚本使IE实现代理上网的教程

    用Python编写脚本使IE实现代理上网的教程

    这篇文章主要介绍了用Python编写脚本使IE实现代理上网的教程,“著名的”goagent代理也是基于同样原理实现,需要的朋友可以参考下
    2015-04-04
  • 解决Mac下使用python的坑

    解决Mac下使用python的坑

    今天小编就为大家分享一篇解决Mac下使用python的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Python 转移文件至云对象存储的方法

    Python 转移文件至云对象存储的方法

    对象存储(Cloud Object Storage,COS)是一种存储海量文件的分布式存储服务,具有高扩展性、低成本、可靠安全等优点。这篇文章主要介绍了Python 转移文件至云对象存储,需要的朋友可以参考下
    2021-02-02
  • Python字节串类型bytes及用法

    Python字节串类型bytes及用法

    这篇文章介绍了Python字节串类型bytes及用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • Python入门教程(二十一)Python的数组

    Python入门教程(二十一)Python的数组

    这篇文章主要介绍了Python入门教程(二十一)Python的数组,数组是一种特殊变量,数组可以在单个名称下保存多个值,我们可以通过引用索引号来访问这些值,需要的朋友可以参考下
    2023-04-04
  • 学会这29个常用函数,你就是Pandas专家

    学会这29个常用函数,你就是Pandas专家

    Pandas 无疑是 Python 处理表格数据最好的库之一,但是很多新手无从下手,这里总结出最常用的 29 个函数,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-11-11
  • 深入浅析python继承问题

    深入浅析python继承问题

    这篇文章主要介绍了深入浅析python继承问题的相关资料,非常不错,感兴趣的朋友一起看看吧
    2016-05-05
  • Python接口传输url与flask数据详解

    Python接口传输url与flask数据详解

    这篇文章主要介绍了Python通过接口传输url与flask数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • flask结合jinja2使用详解

    flask结合jinja2使用详解

    本文主要介绍了flask结合jinja2使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03

最新评论