Model :强大的数据库操作,弱小的数据验证。
Form: 强大的数据验证功能
ModelForm: 二者结合,强大的数据验证,适中的数据库操作
Model
Model的校验使用
1.先在model类中提供clean方法,改方法内实现判断逻辑
2.在视图函数中利用model类的对象.full_clean()方法调用model类中的clean方法,实现校验
案例:
- models.py
from django.db import models
from django.core.exceptions import ValidationError
class News(models.Model):
title = models.CharField(max_length=32)
# 验证错误会输出到errors中去
def clean(self):
if self.title == "root":
raise ValidationError("title不能是root")
views.py
def fm(request):
obj = models.News(title='root')
# full_clean就进行了验证,如果要是有errors的话,就直接报错,所以在进行验证的时候,我们要自己做try判断
try:
obj.full_clean() # 进行model的验证
obj.save()
##报错 django.core.exceptions.ValidationError: {'__all__': ['title不能是root']}
return render(request,"form.html",locals())
Modelform
from django.forms import ModelForm
使用
写一个继承了ModelForm的类
class StudentList(ModelForm):
# 如果想增加一个字段,就在class Meta 之前写这个字段
email = fields.CharField()
class Meta:
model = models.Student # 对应的Model中的类
fields = "__all__" # 字段,如果是__all__,就是表示列出所有的字段
exclude = [] # 排除的字段
labels = {} # 提示信息
help_texts = {} # 帮助提示信息
widgets = {} # 自定义插,给字段input框添加样式
error_messages = {} # 自定义错误信息
# error_messages用法:
error_messages = {
'name':{'required':"用户名不能为空",},
'age':{'required':"年龄不能为空",},
}
# widgets用法,比如把输入用户名的input框改为Textarea
# 首先得导入模块
from django.forms import widgets as wid
widgets = {
"name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性
}
# labels,自定义在前端显示的名字
labels= {
"name":"用户名",
"age" : "年龄"
}
渲染页面
- views.py
def test1(request):
if request.method == 'GET':
student_list = StudentList()
return render(request,'student.html',{'student_list':student_list})
注意: 所有的字段渲染到前端都是获取用户输入的input标签
- student.html
{% for student in student_list %}
<p>{{ student.label }}{{ student }}</p>
{% endfor %}
student.label ,拿到数据库中每个字段的verbose_name ,如果没有设置这个属性,拿到的默认就是字段名
student.errors.0 拿到错误信息
student.field,是拿到每个字段
增加数据
def test2(requesst):
if request.method == "POST":
obj = StudentList(data = request.POST) # 将数据传入校验
if obj.is_valid(): # 校验数据,正确返回True
obj.save() # 保存数据 modelform现在可以直接save就可以,save的时候可以保存一对多、多对多的数据
else:
print(obj.errors)
return render(request, "mf.html", locals())
修改数据
def edit(request,nid):
if request.method == "GET":
model_obj = models.Student.objects.get(id=nid) ##获取model对象
obj = StudentList(instance=model_obj)
else:
model_obj = models.Student.objects.get(id=nid)
obj = StudentList(request.POST,instance=model_obj) ##修改的时候是需要instance 的!如果没有则默认就是增加数据的
if obj.is_valid():
# obj.save() ##他里面的源码默认是commit=True 会帮你第三张表一起修改了。而在django是可以自己手动指定修改的
mobj = obj.save(commit=False) #要是commit为False的话,他会返回一个model的对象、点击commit看源码
mobj.save() ##保存自己表中数据
mobj.save_m2m() ##修改第三张表中的数据,而你要在这二者之间是可以做,一些你想做的事情的
return render(request,"mf.html",locals())
ModelForm还支持所有form的功能,比如钩子,所以我们就可以通过钩子来自定义验证规则
写法和forms的写法一样:
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ('name', 'title')
def clean_name(self):
if ...
return self.clean_data['name']
else:
raise ValidationError(‘sdgsadga’)
...