zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    〖Linux〗Kubuntu设置打开应用时就只在打开时的工作区显示
    〖Linux〗Kubuntu, the application 'Google Chrome' has requested to open the wallet 'kdewallet'解决方法
    unity, dll is not allowed to be included or could not be found
    android check box 自定义图片
    unity, ios skin crash
    unity, Collider2D.bounds的一个坑
    unity, ContentSizeFitter立即生效
    类里的通用成员函数应声明为static
    unity, Gizmos.DrawMesh一个坑
    直线切割凹多边形
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9418504.html
Copyright © 2011-2022 走看看