• 【python】-- Django ModelForm


    Django ModelForm

    Django的ModelForm的验证方式相比较form + Model的验证方式有下列区别:

    • ModelForm没有form + Model的低耦合性
    • ModelForm更适合小型项目,而form + Model则无此限制
    • 都是继承BaseForm类,因此也能使用BaseForm中的三个内置钩子

    一、ModelForm简单示例:

    1、进行modelForm实例之前先在models中创建两张表

    from django.db import models
     
    # Create your models here.
     
    class UserType(models.Model):
        caption = models.CharField(max_length=32)
     
    class UserInfo(models.Model):
        username = models.CharField(max_length=32)
        email = models.EmailField()
        user_type = models.ForeignKey(to="UserType",to_field='id',on_delete=models.CASCADE)
    

    2、在form.py中创建ModelForm

    from app01 import models
    from django import forms
    from django.forms import fields
     
    class UserInfoModelForm(forms.ModelForm): #还是在forms里面,需要继承modelform
     
        class Meta:
            model = models.UserInfo  #表示去哪一个类里面去获取字段
            fields = '__all__' #能获取字段,也可以对这张表进行增删改查,all表示展示所有列
            #fields = ['username',]  #只选择username列,这个是UserInfo中的字段
            #exclude = ["username"] #排除username字段,展示其他字段
    

    3、在view.py中设置验证函数

    def index(request):
        if request.method == "GET":
            obj = UserInfoModelForm()  #验证时,创建modelform对象
            return render(request,'index.html',{'obj':obj})
        elif request.method == "POST":
            obj = UserInfoModelForm(request.POST) #在views函数里面做校验
            return  render(request,'index.html',{'obj':obj})
    

    4、templas中的HTML模板设置

    <body>
        <form>
            {{ obj.as_p }}
            <input type="submit" value="提交"/>
        </form>
    </body>
    

    二、ModelForm中的内置组件、数据保存、示例

    1、ModelForm除modle、fields、exclude组件外,其他组件介绍:

    ModelForm
        class Meta:
            model,                           # 对应Model的
            fields=None,                     # 字段
            exclude=None,                    # 排除字段
            labels=None,                     # 提示标签设置
            """
            labels = {
                'username':'用户名',
                'email':'邮箱',
            }
            """
            help_texts=None,                 # 输入框后的帮助提示信息
            """
            help_texts = {
                'username':'....',
                'email':'xxx@126.com',
            }
    
            """
            widgets=None,                    # 自定义插件
            """
            from django.forms import widgets as Fwidgets  #需要导入html插件,并且需要重新命名,因为跟关键字重复了
    
            #html插件
            widgets = {
                "username":Fwidgets.Textarea(attrs={'class':'c1'})  #加上属性
            }
            """
            error_messages=None,             # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
            """
            error_messages = {
                    "__all__":{
                        #定义整体的错误信息
                    },
                    'email':{
                        'required':'邮箱不为空', # 根据required是code值
                        'invalid':"邮箱格式错误"
                    }
            }
            """
            field_classes=None               # 自定义字段类 (也可以自定义字段)
            """
            #把标签的格式转换为其他格式,这边需要导入fields,但是需要重新起一个别名不然会跟自身的fields冲突,就会报错
            from django.forms import fields as Ffields #导入fields,并且取一个别名
            field_classes = {
                'email':Ffields.URLField #把email格式转换为url格式
            }
            """
            localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
            """
            如:
                数据库中
                    2016-12-27 04:10:57
                setting中的配置
                    TIME_ZONE = 'Asia/Shanghai'
                    USE_TZ = True
                则显示:
                    2016-12-27 12:10:57
            """
    
            # ##自定义字段
            """
            #modelform可以自定义一些字段,比如10天免登录,这个东西不需要提交到后台的
            class UserInfoModelForm(forms.ModelForm):
                #自定义字段
                is_rmb = Ffields.CharField(
                    widget=Fwidgets.CheckboxInput() #modelform可以自定义一些字段,比如10天免登录,这个东西不需要提交给后台的
                )
             
                class Meta:
                    model = models.UserInfo
             
                    fields = "__all__"
    
            """
    

    2、models下ForeignKey、ManyToMany的数据保存

     1 class UserType(models.Model):
     2     caption = models.CharField(max_length=32)
     3  
     4  
     5 class UserGroup(models.Model):
     6     name = models.CharField(max_length=32)
     7  
     8 class UserInfo(models.Model):
     9     username = models.CharField(max_length=32)
    10     email = models.EmailField()
    11     user_type = models.ForeignKey(to="UserType",to_field='id',on_delete=models.CASCADE)
    12     u2g = models.ManyToManyField(UserGroup)  #跟上面的UserGroup建立多对多关系
    models
    #1对1的外键,验证通过后,save()一下,数据就直接可以保存在数据库了
    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() #验证成功之后,是直接保存在数据库中
            """
            form + model中的验证函数
            # print(obj.is_valid())
            # print(obj.cleaned_data)
            # print(obj.errors.as_json())
            """
            return  render(request,'index.html',{'obj':obj})     
    ForeignKey
     1 def index(request):
     2     if request.method == "GET":
     3         obj = UserInfoModelForm()
     4         return render(request,'index.html',{'obj':obj})
     5     elif request.method == "POST":
     6         obj = UserInfoModelForm(request.POST)
     7         if obj.is_valid():
     8             # commit为true时将会同时保存回将UserInfo表和其多对多关系表同时进行保存,为false时什么都不会做,需要自己手动保存UserInfo表和其多对多关系表
     9             obj.save(commit=True)
    10             
    11             instance = obj.save(commit=False)   # 什么保存操作都不回做
    12             instance.save()  # 这个不等于obj.save(),它只保存当前这个表数据,不会保存其多对多关系表
    13             obj.save_m2m()  # 保存其多对多关系表
    14         return  render(request,'index.html',{'obj':obj})
    ManyToMany

    3、示例

     1 from app01 import models
     2 
     3 
     4 def user_list(request):
     5     li = models.UserInfo.objects.all().select_related('user_type')  #select_related 只能是外键,不能是多对多
     6     return render(request,'user_list.html',{'li':li})
     7 
     8 def user_edit(request,nid):
     9     if request.method == "GET":
    10         user_obj = models.UserInfo.objects.filter(id=nid).first()
    11         mf = UserInfoModelForm(instance=user_obj)  #把对象传进来,在前端就能显示默认值
    12         return render(request,'user_edit.html',{'mf':mf,'nid':nid})
    13     elif request.method == "POST":
    14         user_obj = models.UserInfo.objects.filter(id=nid).first()
    15         mf = UserInfoModelForm(request.POST,instance=user_obj)  #我把数据提交过来了,并且我拿到对哪个对象进行更新数据
    16         if mf.is_valid():
    17             mf.save()
    18         else:
    19             print(mf.errors.as_json())
    20         return render(request,'user_edit.html',{'mf':mf,'nid':nid})
    view.py
    <body>
        <ul>
            {% for row in li %}
                <li>{{ row.username }}-{{ row.user_type.caption }}-<a href="/edit-{{ row.id }}/">编辑</a></li>
            {% endfor %}
        </ul>
    </body>
    user_list.html
    <body>
        <form method="post" action="/edit-{{ nid }}/">
            {{ mf.as_p }}
            <input type="submit" value="提交"/>
        </form>
    </body>
    user_edit.html
  • 相关阅读:
    病历管理系统(附源码)
    2013年未之wpf项目乱述
    非农行情的做单策略
    Open Source Trading Platforms ( who needs mt4 ?)
    【原创】如何获得近10年的1分钟完整历史数据并导入MT4
    MetaTrader 4客户端的秘密
    六张图教你交易美国5月非农数据
    创业手札
    如果想开公司,你必须了解这些!!创业的人收藏吧!!
    如何开设港股和美股投资账户
  • 原文地址:https://www.cnblogs.com/Keep-Ambition/p/9769093.html
Copyright © 2020-2023  润新知