• Python学习---ModelForm拾遗180325


    image

    ModelForm适用于前台验证和后台直接操作数据库的前后台未做分离,可以一次执行验证和保存数据的场景。

    注意:  1.  ModelForm里面没有删除方法,需要手动删除内容

    2. ModelForm里面也可以像Form里面一样自定义clean_email()和clean()方法进行数据正确性的验证【post_clean()方法需要自定义try...except

    ModelForm创建信息

    settings.py

    INSTALLED_APPS = [
       ...
     'app01',   # 注册app
    ]
    STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)  # 现添加的配置,这里是元组,注意逗号
    TEMPLATES = [
       ...
       'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ]

    urls.py

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url, include
    from app01 import views
    urlpatterns = [
       url('modelFormDemo/', views.modelFormDemo),
    ]

    views.py

    from django.shortcuts import render, redirect, HttpResponse
    from app01 import models
    # ModelForm实例
    from django import forms as modelForm
    from app01 import models
    class UserModelForm(modelForm.ModelForm):
        # 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据
        class Meta:
            # 说明指向,指定去执行U里面的内容
            model = models.U
            # 指定类中的字段,告诉ModelForm帮我们处理多少字段
            fields = '__all__'   # 这里是帮我们处理所有字段
    
    def modelFormDemo(request):
        if request.method == "GET":
            obj = UserModelForm()
            return render(request, 'modelFormDemo.html', {"obj":obj})
        else :
            obj = UserModelForm(request.POST)
            if obj.is_valid():
                data = obj.clean()
                print('正确数据:', data)
                #  这个是以前我们Model操作来进行增加数据:models.U.objects.create(**data)
                obj.save()  # 这个是ModelForm直接帮我们添加数据,同样也适用于多对多的情况
            err = obj.errors
            print('错误数据:', err)
            return render(request, 'modelFormDemo.html', {"obj":obj})
    

    templates/modelFormDemo.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        {#as_p是从BaseForm里面的方法#}
        <form action="/modelFormDemo/" method="POST">
            {{ obj.as_p }}
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    models.py

    from django.db import models
    class U(models.Model):
        id = models.AutoField(primary_key=True)  # AutoField必须是主键,才能自定义该列
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        userType = models.ForeignKey("UT", on_delete=True)  # 1对多[无法用自定义,有约束关系]
    
    class UT(models.Model):
        caption = models.CharField(max_length=32)
        def __str__(self):
            return self.caption

    页面显示;

    image

    初始化数据库

    python manage.py makemigrations
    python manage.py migrate
    
    

    ModelForm之实时更新下拉框数据

    settings.py

    INSTALLED_APPS = [
       ...
     'app01',   # 注册app
    ]
    STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)  # 现添加的配置,这里是元组,注意逗号
    TEMPLATES = [
       ...
       'DIRS': [os.path.join(BASE_DIR, 'templates')],
    ]

    urls.py

    from django.contrib import admin
    from django.urls import path
    from django.conf.urls import url, include
    from app01 import views
    urlpatterns = [
        url('edit_UserModelForm-(d+)/', fm.edit_UserModelForm),
    ]

    views.py

    from django.shortcuts import render, redirect, HttpResponse
    from app01 import models
    # ModelForm实例
    from django import forms as modelForm
    class UserModelForm(modelForm.ModelForm):
        # 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据
        class Meta:
            # 说明指向,指定去执行U里面的内容
            model = models.U
            # 指定类中的字段,告诉ModelForm帮我们处理多少字段
            fields = '__all__'   # 这里是帮我们处理所有字段
    
    # 修改ModelForm内容
    def edit_UserModelForm(request, nid):
        if request.method == "GET":
            obj_model = models.U.objects.get(id=nid)  # 后台数据库的数据
            obj = UserModelForm(instance=obj_model)  # 把数据库的数据给了ModelForm
            return render(request, 'modelFormDemo.html', {"obj": obj})  # 进行页面显示
        else:
            obj_model = models.U.objects.get(id=nid)  # 后台数据库的数据
            # 如果有instance则修改,没有则添加新数据
            obj = UserModelForm(request.POST, instance=obj_model)  # 获取前台提交的数据进行更新操作
            if obj.is_valid():
                data = obj.clean()
                print('正确数据:', data)
                #  这个是以前我们Model操作来进行增加数据:models.U.objects.create(**data)
                obj.save()  # 这个是ModelForm直接帮我们添加数据,同样也适用于修改数据的情况
            return render(request, 'edit_modelFormDemo.html', {"obj": obj, 'nid':nid})  # 进行页面显示

    templates/edit_modelFormDemo.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        {#as_p是从BaseForm里面的方法#}
        <form action="/edit_UserModelForm-{{ nid }}/ " method="POST">
            {{ obj.as_p }}
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    models.py

    from django.db import models
    class U(models.Model):
        id = models.AutoField(primary_key=True)  # AutoField必须是主键,才能自定义该列
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        userType = models.ForeignKey("UT", on_delete=True)  # 1对多[无法用自定义,有约束关系]
    
    class UT(models.Model):
        caption = models.CharField(max_length=32)
        def __str__(self):
            return self.caption

    页面显示;

    image

    image

    初始化数据库

    python manage.py makemigrations
    python manage.py migrate
    

    ModelForm之save()方法分析

    save()方法的集成度非常高,帮我们可以保存当前表的数据也可以保存多对多表的数据,一对多也是在当前表中,内部默认做了这些事

    image

    手动提交内容:

    image

    ModelForm之Meta的配置选项

    ModelForm
    a.class Meta:
        model,           # 对应Model的
        fields = None,   # 字段
        exclude = None,  # 排除字段
        labels = None,   # 提示信息
    labels = {‘email’:‘邮箱’,’username’:’用户名’}
        help_texts = None,  # 帮助提示信息
        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实例

    views.py

    from django import forms as modelForm
    from app01 import models
    # 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据
    class UserModelForm(modelForm.ModelForm):
    # 相当于在Model中U类的基础上有新添加了一个字段,属自定制内容
    # 如果有跟数据库内的字段重名了,则会覆盖数据库字段的验证功能[Email验证功能]
    # email = forms.CharField()  -->此时就是一个普通的char类型,遵循Form优先的原则
    # 总结一下就是: 如果跟数据库不重名,则页面增加一条输入框; 
    # 如果重名,则会覆盖原来【Form优先】
    # 适用于那种一个月自动登录功能。可以从用户处多拿一个字段到后台进行验证功能
    pwd = forms.CharField()   # 此时数据库内并无此字段,这里添加后页面会增加此字段
        class Meta:
            # 说明指向,指定去执行U里面的内容【只能指定一个Model类】
            model = models.U
            # 指定类中的字段,告诉ModelForm帮我们处理多少字段
            fields = '__all__'   # 这里是帮我们处理所有字段,包括多对多的数据
            # fields = ['name', 'email']  # 处理某几个字段
            # exclude = ['name']   # 排除username的页面显示
            labels = {
                'name': '用户名',
                'email': '邮 箱'
            }
            help_texts = {
                'email':"*",
                'name':'请输入姓名'
            }
            # 自定义插件
            from django.forms import widgets as ws
            from django.forms import forms as ff
            widgets = {
                'email': ws.Textarea()
            }
            error_messages = {
    '__all__':{‘required’:‘必填内容’},# 全局错误信息集
                'name': {'required':'必填项', 'invalid':'格式错误'}
            }
            # 自定义字段类,进行二次验证
            field_classes = {
                'name':  ff.EmailField  # 虽然数据库时CharField,这里要求页面用EmailField进行正则验证
            }

    models.py

    from django.db import models
    class U(models.Model):
        id = models.AutoField(primary_key=True)  # AutoField必须是主键,才能自定义该列
        name = models.CharField(max_length=32)
        email = models.CharField(max_length=32)
        userType = models.ForeignKey("UT", on_delete=True)  # 1对多[无法用自定义,有约束关系]
    class UT(models.Model):
        caption = models.CharField(max_length=32)
        def __str__(self):
            return self.caption

    ModelForm操作:http://www.cnblogs.com/wupeiqi/articles/6229414.html

  • 相关阅读:
    Java day03第三课流程控制
    java day02第二课基本数据类型、修饰符、运算符
    Objective-C 枚举类型和字符串互转方案
    UISlider
    ios中AES和RSA 加密
    1. SEL和IMP(动态性)
    《iOS开发进阶》
    【旧事重提】iOS中文件读写
    Apple移动设备处理器指令集 armv6、armv7、armv7s及arm64
    Unity3D 与 Xcode的结合
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9418504.html
Copyright © 2020-2023  润新知