Form与ModelForm-下拉框或者多选注意//及字段补充
一、Form
设计一张普通model表:
class UserInfo(models.Model): name = models.CharField(verbose_name='员工姓名', max_length=16) username = models.CharField(verbose_name='用户名', max_length=32) password = models.CharField(verbose_name='密码', max_length=64) email = models.EmailField(verbose_name='邮箱', max_length=64) depart = models.ForeignKey(verbose_name='部门', to="Department")
现在我们将這个表 继承form:
class UserInfoForm(Form): name = fields.CharField(required=True,error_messages={'required':'用户名不能为空'}) email = fields.EmailField(required=True)
生成了form以后,我们可以在前端直接使用form类的实例。form帮我们生成了标签,然后再前端进行渲染。
那么问题就来了,如果我想给model表中的depart生成一个下拉框,该如何使用form进行生成呢?
容易想到的就是 如下:
class UserInfoForm(Form): name = fields.CharField(required=True,error_messages={'required':'用户名不能为空'}) email = fields.EmailField(required=True) depart = fields.ChoiceField(choices=Department.object.value_list('id','title'))
但是上面存在一个问题,那就是新添加的数据无法在页面上显示出来,只有当项目重启之后,才会显示最新添加的结果。我们来分析一下原因:
我们知道,类中,除了方法或函数以外,在程序执行过程中,类也会执行,也就是说,当执行到UserInForm类的时候,会依次进行实例化name,email,depart这三个变量,注意,当实例化depart变量的时候,会进行数据库操作,也就是说,只要程序不重启,這个取出数据永远只是第一次程序期启动时取出的数据。既然,我们发现了问题,那么就有两种结局措施。
Solution 1:
from django.forms import Form from django.forms import fields from django.forms import widgets from django.forms.models import ModelChoiceField from app01 import models class UserInfoForm(Form): name = fields.CharField(required=True,error_messages={'required':'用户名不能为空'}) email = fields.EmailField(required=True) part = fields.ChoiceField()
def __init__(self,*args,**kwargs): super(UserInfoForm,self).__init__(*args,**kwargs) self.fields['part'].choices = models.Department.objects.values_list('id','title')
延迟取数据操作,也就是说,取数据每次发生在实例化的时候!
Solutiion 2:
from django.forms import Form from django.forms import fields from django.forms import widgets from django.forms.models import ModelChoiceField from app01 import models class UserInfoForm(Form): name = fields.CharField(required=True,error_messages={'required':'用户名不能为空'}) email = fields.EmailField(required=True) part = ModelChoiceField(queryset=models.Department.objects.all())
用内置的ModelChoiceField来进行实例化,這个实例化过程与上面的两步是等价!
二、Form字段类型补充
1、内置Form可选类型
BooleanField CharField(maxlength) ChoiceField TypedChoiceField DateField/DateTimeField(auto_now,auto_now_add)
DecimalField DurationField EmailField FileField(upload_to) FilePathField FloatField(max_digits,decimal_places)
ImageField(upload_to) IntegerField GenericIPAddressField MultipleChoiceField TypedMultipleChoiceField
NullBooleanField RegexField SlugField TimeField URLField UUIDField MultiValueField SplitDateTimeField
ModelChoiceField ModelMultipleChoiceField
2.可选属性
required # 取消必填 如:forms.CharField(required=False) label #取消默认名称 如:forms.CharField(label='Your name') initial # 给标签赋初值 如:url = forms.URLField(initial='http://') import datetime day = forms.DateField(initial=datetime.date.today)
widget#给标签添加属性 如:comment = forms.CharField(widget=forms.Textarea) #将默认的input框变为textarea help_text#添加提示信息 如sender = forms.EmailField(help_text='A valid email address, please.') error_messages#name = forms.CharField(error_messages={'required': 'Please enter your name'})