• 10.Django ModelForm


    ModelForm

     1.ModeForm简单验证

    from django.db import models
    
    # Create your models here.
    
    class UserInfo(models.Model):
        # verbose_name 等同于Form类里面的label
        username = models.CharField(verbose_name='用户',max_length=32)
        email = models.EmailField(verbose_name='邮件')
        user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
    
    
    class UserType(models.Model):
        caption = models.CharField(max_length=32)
    
        def __str__(self):          #打印名称,不写显示的是obj对象
            return self.caption
    
    models.py
    model.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/index/" method="post">
            {% csrf_token %}
            {{ obj.as_p }}
            <input type="submit" value="提交"/>
        </form>
    
    </body>
    </html>
    
    index.html
    index.html

    views.py

    from django.shortcuts import render,redirect
    from app01 import models
    from django import forms
    from django.forms import fields
    
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo  # 去UserInfo类中获取数据
            fields = '__all__'  # __all__ 代指所有字段
            # fields = ['username','email']       #指定显示的字段
            # exclude = ['username']      #不显示的字段
    
    def index(request):
        if request.method == 'GET':
            obj = UserInfoModelForm()
            return render(request,'index.html',{'obj':obj})
        elif request.method == 'POST':
            obj = UserInfoModelForm(request.POST)
            result = obj.is_valid()
            if result:
                print(obj.cleaned_data)             #如果models里没有__str__方法,则user_type获取
                                                            #到的是一个对象,可直接根据对象进行操作
                print(obj.cleaned_data['user_type'])
                # {'username': 'James', 'user_type': < UserType: 超级用户 >, 'email': 'ffd@fdsf.com'}
                # 超级用户
            else:
                print(obj.errors)
            return render(request,'index.html',{'obj':obj})

    注:ModelForm最终继承了BaseForm,BaseForm里面具有is_valid方法,所以ModelForm也可以用is_valid进行验证

     2.ModelForm组件

    ModelForm
        a.  class Meta:
                model,                           # 对应Model的
                fields=None,                     # 字段
                exclude=None,                    # 排除字段 
                labels=None,                     # 提示信息  labels ={'username':'用户名'}可写多个
                help_texts=None,                 # 帮助提示信息    help_texts = {'username':'help info'}
                widgets=None,                    # 自定义插件
                error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
                field_classes=None               # 自定义字段类 (也可以自定义字段)
                localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
                如:
                    数据库中
                        2016-12-27 04:10:57
                    setting中的配置
                        TIME_ZONE = 'Asia/Shanghai'
                        USE_TZ = True
                    则显示:
                        2016-12-27 12:10:57
        b. 验证执行过程
            is_valid -> full_clean -> 钩子 -> 整体错误
     
        c. 字典字段验证
            def clean_字段名(self):
                # 可以抛出异常
                # from django.core.exceptions import ValidationError
                return "新值"
        d. 用于验证
            model_form_obj = XXOOModelForm()
            model_form_obj.is_valid()
            model_form_obj.errors.as_json()
            model_form_obj.clean()
            model_form_obj.cleaned_data
        e. 用于创建
            model_form_obj = XXOOModelForm(request.POST)
            #### 页面显示,并提交 #####
            # 默认保存多对多
                obj = form.save(commit=True)
            # 不做任何操作,内部定义 save_m2m(用于保存多对多)
                obj = form.save(commit=False)
                obj.save()      # 保存单表信息
                obj.save_m2m()  # 保存关联多对多信息
     
        f. 用于更新和初始化
            obj = model.tb.objects.get(id=1)
            model_form_obj = XXOOModelForm(request.POST,instance=obj)
            ...
     
            PS: 单纯初始化
                model_form_obj = XXOOModelForm(initial={...})
    
    ModelForm所有组件
    所有组件

    (1)自定义插件widgets

    from django.forms import widgets as Fwidgets    #避免跟widgets重名
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo     #去UserInfo类中获取数据
            fields = '__all__'        #__all__ 代指所有字段
            labels ={'username':'用户名'}
            help_texts = {'username':'...'}
            widgets = {
                'username':Fwidgets.Textarea(attrs={'class':'c1'})
            }

    (2)错误信息error_message

    from django.forms import widgets as Fwidgets    #避免跟widgets重名
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            ---snip---
            error_messages = {
                '__all__':{},       #整体的错误信息
                'email':{'required':'邮箱不能为空'}
            }

    (3)自定义更改字段验证规则field_classses

    from django.forms import fields as Ffields     #避免跟fields重名
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            ---snip---
            field_classes ={
                'email':Ffields.URLField    #把邮件格式改为url格式验证
            }
    from django.shortcuts import render,redirect
    from app01 import models
    from django import forms
    from django.forms import fields
    from django.forms import widgets as Fwidgets
    from django.forms import fields as Ffields     
    
    
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo  # 去UserInfo类中获取数据
            fields = '__all__'  # __all__ 代指所有字段
            labels = {'username': '用户名'}
            help_texts = {'username': '...'}
            widgets = {
                'username': Fwidgets.Textarea(attrs={'class': 'c1'})
            }
            error_messages = {
                '__all__': {},  # 整体的错误信息
                'email': {'required': '邮箱不能为空'}
            }
            field_classes = {
                'email': Ffields.URLField  # 把邮件格式改为url格式验证
            }
    
    def index(request):
        if request.method == 'GET':
            obj = UserInfoModelForm()
            return render(request,'index.html',{'obj':obj})
        elif request.method == 'POST':
            obj = UserInfoModelForm(request.POST)
            result = obj.is_valid()
            if result:
                print(obj.cleaned_data)             #如果models里没有__str__方法,则user_type获取
                                                            #到的是一个对象,可直接根据对象进行操作
                print(obj.cleaned_data['user_type'])
                # {'username': 'James', 'user_type': < UserType: 超级用户 >, 'email': 'ffd@fdsf.com'}
                # 超级用户
            else:
                print(obj.errors)
            return render(request,'index.html',{'obj':obj})
    全部代码

    3.ModelForm创建保存数据

    from django.db import models
    
    # Create your models here.
    
    class UserInfo(models.Model):
        # verbose_name 等同于Form类里面的label
        username = models.CharField(verbose_name='用户',max_length=32)
        email = models.EmailField(verbose_name='邮件')
        user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
        user_group = models.ManyToManyField('UserGroup')
    
    class UserType(models.Model):
        caption = models.CharField(max_length=32)
    
        def __str__(self):          #打印名称,不写显示的是obj对象
            return self.caption
    
    class UserGroup(models.Model):
        groupname = models.CharField(max_length=32)
    
        def __str__(self):          #打印名称,不写显示的是obj对象
            return self.groupname
    models
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/index/" method="post">
            {% csrf_token %}
            {{ obj.as_p }}
            <input type="submit" value="提交"/>
        </form>
    
    </body>
    </html>
    index.html
    from django import forms
    from app import models
    from django.forms import widgets as Fwidgets    #避免跟widgets重名
    from django.forms import fields as Ffields     #避免跟fields重名
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo     #去UserInfo类中获取数据
            fields = '__all__'        #__all__ 代指所有字段
            labels ={'username':'用户名'}
            help_texts = {'username':'...'}
            widgets = {
                'username':Fwidgets.Textarea(attrs={'class':'c1'})
            }
            error_messages = {
                '__all__':{},       #整体的错误信息
                'email':{'required':'邮箱不能为空'}
            }
    
    ModelForm验证
    ModelForm验证

    处理文件

    from django.shortcuts import render
    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()         #默认commit=True,会保存多对多
                # 保存一对多表单
                # instance = obj.save(commit=False)
                # instance.save()
                # 保存多对多数据
                # obj.save_m2m()
            return render(request,'index.html',{'obj':obj})

    4.ModelForm更新和初始化

    描述:打开用户列表,显示用户信息,点击编辑跳转到编辑页面,Input显示选择用户的当前值;提交后,对数据进行更新

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/$', views.index),
        url(r'^list/$', views.user_list),
        url(r'^edit-(d+)', views.user_edit),
    ]
    url.py
    from django.db import models
    
    
    class UserInfo(models.Model):
        # verbose_name 等同于Form类里面的label
        username = models.CharField(verbose_name='用户',max_length=32)
        email = models.EmailField(verbose_name='邮件')
        user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
        user_group = models.ManyToManyField('UserGroup')
    
    class UserType(models.Model):
        caption = models.CharField(max_length=32)
    
        def __str__(self):          #打印名称,不写显示的是obj对象
            return self.caption
    
    class UserGroup(models.Model):
        groupname = models.CharField(max_length=32)
    
        def __str__(self):          #打印名称,不写显示的是obj对象
            return self.groupname
    model.py

    user_list.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <ul>
            {% for row in list %}
                <p>{{ row.username }}--{{ row.user_type.caption }}--<a href="/edit-{{ row.id }}">编辑</a></p>
            {% endfor %}
        </ul>
    </body>
    </html>

    user_edit.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/edit-{{ nid }}" method="post">
            {% csrf_token %}
            {{ obj.as_p }}
            <input type="submit" value="提交" />
        </form>
    
    </body>
    </html>

    views.py

    from django.shortcuts import render,redirect
    from app01 import models
    from django import forms
    from django.forms import fields
    from django.forms import widgets as Fwidgets
    from django.forms import fields as Ffields
    
    
    class UserInfoModelForm(forms.ModelForm):
        class Meta:
            model = models.UserInfo  # 去UserInfo类中获取数据
            fields = '__all__'  # __all__ 代指所有字段
            labels = {'username': '用户名'}
            help_texts = {'username': '...'}
            widgets = {
                'username': Fwidgets.Textarea(attrs={'class': 'c1'})
            }
            error_messages = {
                '__all__': {},  # 整体的错误信息
                'email': {'required': '邮箱不能为空'}
            }
    
    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()         #默认commit=True,会保存多对多
                # 保存一对多表单
                # instance = obj.save(commit=False)
                # instance.save()
                # 保存多对多数据
                # obj.save_m2m()
            return render(request,'index.html',{'obj':obj})
    
    
    def user_list(request):
        if request.method == 'GET':
            list = models.UserInfo.objects.all().select_related('user_type')
            return render(request, 'user_list.html', {'list': list})
    
    
    def user_edit(request, nid):
        if request.method == 'GET':
            user_obj = models.UserInfo.objects.filter(id=nid).first()
            obj = UserInfoModelForm(instance=user_obj)  # instance显示user_obj的对应值
            return render(request, 'user_edit.html', {'obj': obj, 'nid': nid})
        elif request.method == 'POST':
            user_obj = models.UserInfo.objects.filter(id=nid).first()
            obj = UserInfoModelForm(request.POST, instance=user_obj)  # instance更新user_obj而不是添加
            if obj.is_valid():
                # 验证成功直接更新
                obj.save()
            else:
                print(obj.errors.as_json())
            return render(request, 'user_edit.html', {'obj': obj, 'nid': nid})
     
     
     
  • 相关阅读:
    Redis持久化
    环境搭建
    openresty了解基础
    正向代理和反向代理
    Java IO流:(十)字节缓冲流
    Java IO流:(九)缓冲流
    第二节:MySQL软件的卸载(Windows版)
    第一节:MySQL产品的介绍
    第一节:数据库相关知识
    MySQL【目录】
  • 原文地址:https://www.cnblogs.com/gaidy/p/12087931.html
Copyright © 2020-2023  润新知