django组件之Modelform组件

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 %}
    

{{ student.label }}{{ student }}

{% 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’)
        ...

 

你可能感兴趣的:(Django框架)