码迷,mamicode.com
首页 > 其他好文 > 详细

12.ModelForm组件

时间:2020-10-09 21:41:42      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:提示信息   forms   ror   功能   prim   its   type   书籍   man   

一、ModelForm

ModelForm是将Model和Form进行绑定,Form可以自动生成表单的作用,但是每一个forms字段需要自己手动填写,而Model就是数据库包含了所有的数据字段,所以ModelForm有着Form的所有功能也能将Model字段自动转成forms字段。

1、modelform的定义

form和model的结合,会根据在model中的字段转换成对应的form字段,并且生成标签等。

class Book(models.Model):
    nid = model.AutoField(primary_key=true)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5,decimal_place=2)
    publish = models.ForignKey(to=‘Publish‘, to_field=‘nid‘)
    authors = models.ManyToManyField(to=‘Author‘)
    def __init__(self):
        return self.title

modelForm类的写法:

from app01 import models
from django.forms import ModelForm

class BookForm(forms.ModelForm):
    class Meta:
        model = models.Book	# 对应的model类
        fields = "__all__"	# 对应的Model类中字段
        # exclude = [‘title‘]	# 排除的字段
        labels = {
            "title":"书名",	# 用户html页面中显示的名字
            "price": ‘价格‘
        }
        help_texts = {
            ‘title‘: ‘我是帮助信息‘	# 自定义帮助信息
        }
        errors_messages = {
            ‘title‘: {‘required‘: ‘书籍名为空‘}
        }
        widget = {
            "password": forms.wodgets.PasswordInput(attrs={‘class‘:‘c1‘}),
            "publishDate": forms.widgets.DateInput(attrs={"type": ‘date‘}),
        }

1)class Meta常用参数

model = models.Book		# 对应的Model中的类
fields = "__all__"		# 字段,如果是__all__,就是表示列出所有的字段
excluds = None			# 排除的字段
labels = None			# 提示信息
help_texts = None		# 帮助提示信息
widgets = None			# 自定义插件
erros_messages = None	# 自定义错误信息
error_messages = {
    ‘title‘:{‘required‘:‘不能为空‘,}	# 每个字段的错误都可以写
}

2)批量添加样式

class BookForm(forms.ModelForm):    
    #password = forms.CharField(min_length=10) #可以重写字段,会覆盖modelform中的这个字段,modelform下面关于这个字段的设置就会被覆盖,比如设置插件啊,error_messages等等,
    r_password = forms.CharField() #想多验证一些字段可以单独拿出来写,按照form的写法,写在Meta的上面或者下面都可以
    class Meta:
        model = models.Book
        # fields = [‘title‘,‘price‘]
        fields = "__all__" #[‘title‘,‘price‘] 指定字段生成form
        labels = {
            "title": "书名",
            "price": "价格"
        }
        error_messages = {
            ‘title‘:{‘required‘:‘不能为空‘,} #每个字段的错误都可以写
        }
    #如果models中的字段和要验证的字段不是一致的,比如注册时,需要验证密码和确认密码两个字段数据,但是数据库就保存一个密码就行,那么验证是两个,数据保存是一个,就可以再接着写form字段
    r_password = forms.CharField()。    #如果想做一些特殊的验证定制,那么和form一样,也是那两个钩子(全局和局部),写法也是form那个的写法,直接在类里面写:
    #局部钩子:    def clean_title(self):  pass
    #全局钩子    def clean(self):        pass
    def __init__(self,*args,**kwargs): #批量操作
        super().__init__(*args,**kwargs)
        for field in self.fields:            
            #field.error_messages = {‘required‘:‘不能为空‘} #批量添加错误信息,这是都一样的错误,不一样的还是要单独写。
            self.fields[field].widget.attrs.update({‘class‘:‘form-control‘})

2、ModelForm的验证

和普通的Form表单验证类似,ModelForm表单的验证在调用is_valid()或者访问errors属性时隐式调用。

可以像使用Form类一样自定义局部钩子方法和全局钩子方法来实现自定义的校验规则。

如果不重写具体字段并设置validators属性的话,ModelForm是按照模型中字段的validators来校验的。

1)save()方法

每个ModelForm具有一个save()方法,这个方法根据表单绑定的数据创建并保存数据库对象。ModelForm的子类可以实现接受现有的模型实列作为使用关键字参数instance,如果提供此功能,则save()将更新该实例,如果没有则提供一个新的实例。

from myapp.models import Book
from myapp.forms import BookForm
# 根据POST数据创建一个新的form对象
form_obj = BookForm(request.POST)
# 创建书籍对象
new_book = form_obj.save()
# 基于一个书籍对象创建form对象
edit_obj = Book.objects.get(id=1)
# 使用POST提交的数据更新书籍对象
from_obj = BookForm(request.POST, instance=edit_obj)
form_obj.save()

3、创建modelform

#首先导入ModelForm

from django.forms import ModelForm
#在视图函数中,定义一个类,比如就叫StudentList,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,并注意首字母是大写的)
#在这个原类中,有以下属性(部分):

class StudentList(ModelForm):
    class Meta:
        model =Student #对应的Model中的类
        fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
        exclude = None #排除的字段
        #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":"用户名"
        }

然后在url对应的视图函数中实例化这个类,把这个对象传给前端。

def student(request):
    if request.method == "GET":
        student_list = StudentList()
        return render(request,‘student.html‘,{‘student_list‘: sudent_list})

前端只需要{{ student_list.as_p }}所有的字段就出来了,或者for一下。

1)添加记录

保存数据的时候,不需要挨个取数据,只需要save一下。

def student(request):

    if request.method == ‘GET‘:
         student_list = StudentList()
         return render(request,‘student.html‘,{‘student_list‘:student_list})
    else:
         student_list = StudentList(request.POST)
         if student_list.is_valid():
         student_list.save()
         return redirect(request,‘student_list.html‘,{‘student_list‘:student_list})

2)编辑数据

如果不用ModelForm,编辑的时候得显示之前的数据吧,还得挨个取一遍值,如果ModelForm,只需要加一个instance=obj(obj是要修改的数据库的一条数据的对象)就可以得到同样的效果,保存的时候要注意,一定要注意有这个对象(instance=obj),否则不知道更新哪一个数据

from django.shortcuts import render,HttpResponse,redirect
from django.forms import ModelForm
# Create your views here.
from app01 import models
def test(request):
    # model_form = models.Student
    model_form = models.Student.objects.all()
    return render(request,‘test.html‘,{‘model_form‘:model_form})

class StudentList(ModelForm):
    class Meta:
        model = models.Student #对应的Model中的类
        fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
        exclude = None #排除的字段
        labels = None #提示信息
        help_texts = None #帮助提示信息
        widgets = None #自定义插件
        error_messages = None #自定义错误信息
        #error_messages用法:
        error_messages = {
        ‘name‘:{‘required‘:"用户名不能为空",},
        ‘age‘:{‘required‘:"年龄不能为空",},
        }
        #widgets用法,比如把输入用户名的input框给为Textarea
        #首先得导入模块
        from django.forms import widgets as wid #因为重名,所以起个别名
        widgets = {
        "name":wid.Textarea
        }
        #labels,自定义在前端显示的名字
        labels= {
        "name":"用户名"
        }
def student(request):
    if request.method == ‘GET‘:
        student_list = StudentList()
        return render(request,‘student.html‘,{‘student_list‘:student_list})
    else:
        student_list = StudentList(request.POST)
        if student_list.is_valid():
            student_list.save()
            return render(request,‘student.html‘,{‘student_list‘:student_list})

def student_edit(request,pk):
    obj = models.Student.objects.filter(pk=pk).first()
    if not obj:
        return redirect(‘test‘)
    if request.method == "GET":
        student_list = StudentList(instance=obj)
        return render(request,‘student_edit.html‘,{‘student_list‘:student_list})
    else:
        student_list = StudentList(request.POST,instance=obj)
        if student_list.is_valid():
            student_list.save()
            return render(request,‘student_edit.html‘,{‘student_list‘:student_list})

12.ModelForm组件

标签:提示信息   forms   ror   功能   prim   its   type   书籍   man   

原文地址:https://www.cnblogs.com/journeyer-xsh/p/13787468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!