起步
django 表单中有两种字段类型可以使用选择框: choicefield
和 modelchoicefield
。
对于 choicefield
的基本使用是:
1
2
3
4
5
6
7
8
9
10
11
12
|
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>
标签:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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 中提供了一个很好的解决方案。
首先为需要分类的类型创建模型,在另一个模型中用外键关联它:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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
类型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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)
|
最后,在表单中可以如下进行使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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' )
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.hongweipeng.com/index.php/archives/1790/