【python】-- Django ModelForm
Django ModelForm
Django的ModelForm的验证方式相比较form + Model的验证方式有下列区别:
- ModelForm没有form + Model的低耦合性
- ModelForm更适合小型项目,而form + Model则无此限制
- 都是继承BaseForm类,因此也能使用BaseForm中的三个内置钩子
一、ModelForm简单示例:
1、进行modelForm实例之前先在models中创建两张表
from django.db import models # Create your models here. class UserType(models.Model): caption = models.CharField(max_length=32) class UserInfo(models.Model): username = models.CharField(max_length=32) email = models.EmailField() user_type = models.ForeignKey(to="UserType",to_field='id',on_delete=models.CASCADE)
2、在form.py中创建ModelForm
from app01 import models from django import forms from django.forms import fields class UserInfoModelForm(forms.ModelForm): #还是在forms里面,需要继承modelform class Meta: model = models.UserInfo #表示去哪一个类里面去获取字段 fields = '__all__' #能获取字段,也可以对这张表进行增删改查,all表示展示所有列 #fields = ['username',] #只选择username列,这个是UserInfo中的字段 #exclude = ["username"] #排除username字段,展示其他字段
3、在view.py中设置验证函数
def index(request): if request.method == "GET": obj = UserInfoModelForm() #验证时,创建modelform对象 return render(request,'index.html',{'obj':obj}) elif request.method == "POST": obj = UserInfoModelForm(request.POST) #在views函数里面做校验 return render(request,'index.html',{'obj':obj})
4、templas中的HTML模板设置
<body> <form> {{ obj.as_p }} <input type="submit" value="提交"/> </form> </body>
二、ModelForm中的内置组件、数据保存、示例
1、ModelForm除modle、fields、exclude组件外,其他组件介绍:
ModelForm class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 labels=None, # 提示标签设置 """ labels = { 'username':'用户名', 'email':'邮箱', } """ help_texts=None, # 输入框后的帮助提示信息 """ help_texts = { 'username':'....', 'email':'xxx@126.com', } """ widgets=None, # 自定义插件 """ from django.forms import widgets as Fwidgets #需要导入html插件,并且需要重新命名,因为跟关键字重复了 #html插件 widgets = { "username":Fwidgets.Textarea(attrs={'class':'c1'}) #加上属性 } """ error_messages=None, # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS) """ error_messages = { "__all__":{ #定义整体的错误信息 }, 'email':{ 'required':'邮箱不为空', # 根据required是code值 'invalid':"邮箱格式错误" } } """ field_classes=None # 自定义字段类 (也可以自定义字段) """ #把标签的格式转换为其他格式,这边需要导入fields,但是需要重新起一个别名不然会跟自身的fields冲突,就会报错 from django.forms import fields as Ffields #导入fields,并且取一个别名 field_classes = { 'email':Ffields.URLField #把email格式转换为url格式 } """ localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据 """ 如: 数据库中 2016-12-27 04:10:57 setting中的配置 TIME_ZONE = 'Asia/Shanghai' USE_TZ = True 则显示: 2016-12-27 12:10:57 """ # ##自定义字段 """ #modelform可以自定义一些字段,比如10天免登录,这个东西不需要提交到后台的 class UserInfoModelForm(forms.ModelForm): #自定义字段 is_rmb = Ffields.CharField( widget=Fwidgets.CheckboxInput() #modelform可以自定义一些字段,比如10天免登录,这个东西不需要提交给后台的 ) class Meta: model = models.UserInfo fields = "__all__" """
2、models下ForeignKey、ManyToMany的数据保存
1 class UserType(models.Model): 2 caption = models.CharField(max_length=32) 3 4 5 class UserGroup(models.Model): 6 name = models.CharField(max_length=32) 7 8 class UserInfo(models.Model): 9 username = models.CharField(max_length=32) 10 email = models.EmailField() 11 user_type = models.ForeignKey(to="UserType",to_field='id',on_delete=models.CASCADE) 12 u2g = models.ManyToManyField(UserGroup) #跟上面的UserGroup建立多对多关系
#1对1的外键,验证通过后,save()一下,数据就直接可以保存在数据库了 def index(request): if request.method == "GET": obj = UserInfoModelForm() return render(request,'index.html',{'obj':obj}) elif request.method == "POST": obj = UserInfoModelForm(request.POST) if obj.is_valid(): obj.save() #验证成功之后,是直接保存在数据库中 """ form + model中的验证函数 # print(obj.is_valid()) # print(obj.cleaned_data) # print(obj.errors.as_json()) """ return render(request,'index.html',{'obj':obj})
1 def index(request): 2 if request.method == "GET": 3 obj = UserInfoModelForm() 4 return render(request,'index.html',{'obj':obj}) 5 elif request.method == "POST": 6 obj = UserInfoModelForm(request.POST) 7 if obj.is_valid(): 8 # commit为true时将会同时保存回将UserInfo表和其多对多关系表同时进行保存,为false时什么都不会做,需要自己手动保存UserInfo表和其多对多关系表 9 obj.save(commit=True) 10 11 instance = obj.save(commit=False) # 什么保存操作都不回做 12 instance.save() # 这个不等于obj.save(),它只保存当前这个表数据,不会保存其多对多关系表 13 obj.save_m2m() # 保存其多对多关系表 14 return render(request,'index.html',{'obj':obj})
3、示例
1 from app01 import models 2 3 4 def user_list(request): 5 li = models.UserInfo.objects.all().select_related('user_type') #select_related 只能是外键,不能是多对多 6 return render(request,'user_list.html',{'li':li}) 7 8 def user_edit(request,nid): 9 if request.method == "GET": 10 user_obj = models.UserInfo.objects.filter(id=nid).first() 11 mf = UserInfoModelForm(instance=user_obj) #把对象传进来,在前端就能显示默认值 12 return render(request,'user_edit.html',{'mf':mf,'nid':nid}) 13 elif request.method == "POST": 14 user_obj = models.UserInfo.objects.filter(id=nid).first() 15 mf = UserInfoModelForm(request.POST,instance=user_obj) #我把数据提交过来了,并且我拿到对哪个对象进行更新数据 16 if mf.is_valid(): 17 mf.save() 18 else: 19 print(mf.errors.as_json()) 20 return render(request,'user_edit.html',{'mf':mf,'nid':nid})
<body> <ul> {% for row in li %} <li>{{ row.username }}-{{ row.user_type.caption }}-<a href="/edit-{{ row.id }}/">编辑</a></li> {% endfor %} </ul> </body>
<body> <form method="post" action="/edit-{{ nid }}/"> {{ mf.as_p }} <input type="submit" value="提交"/> </form> </body>