zoukankan      html  css  js  c++  java
  • Django之ModelForm组件

     

     一、创建一个ModelForm组件

      1、导入相应模块

        from django.forms import ModelForm

        from django.forms import fields

      2、创建一个类来继承ModelForm(类中继承类,规定)

        class UserModelForm(ModelForm):

          UserInfo表中的字段名=fields.ChoiceField(choices=[(x1,y1),(x2,y2),(x3,y3)],error_messages='错误信息')              #默认情况下在前端会把表字段渲染成一个个input标签,可以通过fields来定制在前端渲染成其他标签,比如select标签,这时x1就会作为value值,y1就会作为文本在前端显示,但是有个缺点是在前端添加的新数据不会自动刷新,解决办法如下(手动挡和自动挡)
          class Meta:
            model = models.UserInfo            #UserInfo 是在model中相关的表名
            fields = "__all__"        #all表示继承表中所有字段,也可以用列表的方式继承某个字段(fields=['表字段1','表字段2','表字段3']),想显示几个字段就写几个字段。

        

          UserInfo表中的字段名=fields.ChoiceField(error_messages='错误信息')     #手动挡,手动刷新

          def __init__(self,*args,**kwargs):      

            super(UserModelForm,self).__init__(*args,**kwargs)

            self.fields['UserInfo表中的字段名'].choices=[(x1,y1),(x2,y2),(x3,y3)]           #得到的是个列表嵌套元组

           from django.forms.models import ModelChoiceField   #自动挡,自动刷新

          UserInfo表中的字段名=ModelChoiceField(queryset=models.Userinfo.all())        #得到的是个对象,但是依赖性差,必须写___str__

      3、函数中调用该类,用于在前端显示models中的字段信息

    注释:get方式是请求数据,post方式是发送数据,增加数据库记录
    def
    user_add(request): if request.method == 'GET': model_form = UserModelForm() #类实例化产生一个对象,该对象就有了该model中所有字段 return render(request,'rbac/user_add.html',{'model_form':model_form}) #将类对象传输到前端页面进行渲染,由于传输的是all,所以model中有几个值就渲染几个。可通过novalidate来禁止浏览器自身渲染 else: model_form = UserModelForm(request.POST) #将客户端发送过来的数据进行类实例化产生一个对象,该对象就有了表字段中所对应的所有客户端的数据 if model_form.is_valid():           #将该对象下的客户数据进行验证,判断如果符合条件则pass model_form.save()             #将客户端符合条件的数据保存起来,直接通过save()方式就可以在数据库中创建数据以及外键对应关系 return redirect('/rbac/users.html') return render(request, 'rbac/user_add.html', {'model_form': model_form})

      4、函数中调用该类,用于在前端显示models中的某一条记录的信息

    注释:更新数据库记录,先返回数据库中记录信息给客户端,然后更新数据库记录
    def
    user_edit(request,pk): obj = models.UserInfo.objects.filter(pk=pk).first() #在数据库中查找,得到一条记录对象 if not obj: return redirect('/rbac/users.html') if request.method == 'GET': model_form = UserModelForm(instance=obj) #将在数据库中查找到的数据进行实例化产生一个对象,该对象就分装了该数据的所有相关信息 return render(request,'rbac/user_edit.html',{'model_form':model_form}) else: model_form = UserModelForm(request.POST,instance=obj) #必须告诉UserModelForm类是对那条记录进行更新,如果不写就是添加 if model_form.is_valid(): model_form.save() return redirect('/rbac/users.html') return render(request, 'rbac/user_edit.html', {'model_form': model_form})

       5、前端通过as_p的方式进行快速部署

    {{ model_form.as_p }}
    

       6、前端可以通过''.''方式选择部署

    {{ model_form.label }}   #主要表示的是数据的表头信息,即model类中的表字段信息
    {{ model_form }}      #主要表示的是需要添加的数据格式,即input框select框等。
    {{ model_form.errors}}   #主要表示的是数据的错误信息,可以通过errors.0的方式取第一条错误信息
    

       7、前端补充知识

    {{ model_form.field}}    #主要是得到的是表中的哪个外键字段以及外键字段对应的数据,得到的是个类似于<django.forms.models.ModelChoiceField object at 0x00000212D934D780>的内存地址,只有是外键的字段才会显示出来
    {{ model_form.field.queryset}} #主得到的是表中所有字段对象
    {{ model_form.auto_id}} #主得到的是表每个字段的id
    {{ model_form._meta.app_label}} #主得到的是使用字段的app名称

    {{ model_form._meta.model_name}} #主得到的是使用字段的表名
    {{ model_form.field.queryset.model}} #主得到的是表的类名
     总结:具体使用方法可以参考fields源码

    二、总结

    ModelForm
             class Meta:
                model=,                          # 对应Model的表名
                fields=None,                     # 对应的表字段名,多个时用列表
                exclude=None,                    # 对应的表字段名,只不过是排除字段多个时用列表
                labels=None,                     # 改变原有的用户提示信息  {‘字段名’:‘提示信息’}
                help_texts=None,                 # 帮助提示信息    {‘字段名’:‘帮助提示信息’}
           widgets=None,           # 自定义插件属性需要先导入 from django.forms import widgets 然后
                                widgets = {  "username":widgets.Textarea(attrs={'class':'c1'}) }

                              
    error_messages=None, # 自定义错误信息字典的形式{'表字段': {'required':'错误提示'}'表字段': {'required':'错误提示'},}
                               (整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
    field_classes=None # 自定义字段类型(type) (也可以自定义字段) {‘字段名’:fields.类型名} ,用之前徐先导入from django.forms import fields 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): #制作钩子,在在ModelForm自带验证客户端数据条件的前写入自己的验证条件,如果没通过就直接走自己的验证机制 # 可以抛出异常 # 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={...})

    三、个人总结

      1、ModelForm是结合和form和model两种方法的特性,换句话说就是这两种方法的结合体。所以ModelForm既可以用form中的方法也可以使用model中的方法。

      2、代码

    from django.forms import ModelForm
    from django.forms import widgets as wid
    from django.forms import fields as fld
    class UserModelForm(ModelForm):
    
        # use = fld.CharField()  #自定制字段
    
        class Meta:
            model = models.UserInfo
            fields = "__all__"
            # fields = ['username','nickname',]  #显示表中的某个字段
            # exclude = ['username',]     #显示出该字段外的表中所有字段
            # error_messages = {
            #     "username": {'required':'用户名不能为空'}   #为表中字段自定制错误信息
            # }
            # widgets = {
            #     "username":wid.Textarea(attrs={'class':'c1'})  #为 表中字段自定义标签类型并自定义样式名称
            # }
            # labels = {
            #     'username':'用户名'   #自定义提示信息
            # }
            # help_texts = {
            #     'username': '别瞎写,瞎写打你哦'  #自定义用户提示信息
            # }
            #
            # field_classes = {
            #     'username': fld.EmailField   #自定义标签类型
            # }
    
        # def clean_email(self):   #自定义某个字段钩子
        #     pass
        #
        # def clean_nickname(self):
        #     pass
        #
        # def clean(self):          #自定义所有钩子
        #     pass 
    
    def user_add(request):
        # 现在的你# 创建Form类:
        if request.method == 'GET':
            model_form = UserModelForm()
            return render(request,'rbac/user_add.html',{'model_form':model_form})
        else:
            model_form = UserModelForm(request.POST)
            if model_form.is_valid():
                model_form.save()
                return redirect('/rbac/users.html')
    
            return render(request, 'rbac/user_add.html', {'model_form': model_form})
    
    def user_edit(request,pk):
        obj = models.UserInfo.objects.filter(pk=pk).first()
    
        if not obj:
            return redirect('/rbac/users.html')
        if request.method == 'GET':
            model_form = UserModelForm(instance=obj)
            return render(request,'rbac/user_edit.html',{'model_form':model_form})
        else:
            model_form = UserModelForm(request.POST,instance=obj)
            if model_form.is_valid():
                model_form.save()
                return redirect('/rbac/users.html')
            return render(request, 'rbac/user_edit.html', {'model_form': model_form})
    

       注释:novalidate 可以禁止掉浏览器自带的form验证(HTML5给form元素新增了一个novalidate属性,指定为true或者就直接仅仅声明这个属性的时候,不会验证字段)

       

        

  • 相关阅读:
    鸡啄米vc++2010系列19(常用控件:静态文本框)
    鸡啄米vc++2010系列18(颜色对话框)
    鸡啄米vc++2010系列17(字体对话框)
    鸡啄米vc++2010系列16(文件对话框)
    鸡啄米vc++2010系列15(消息对话框)
    鸡啄米vc++2010系列14(一般属性页对话框的创建)
    鸡啄米vc++2010系类13(向导对话框的创建)
    鸡啄米vc++2010系列12(属性页对话框)
    鸡啄米vc++2010系列11(非模态对话框的创建)
    鸡啄米vc++2010系列10(模态对话框及其弹出过程)
  • 原文地址:https://www.cnblogs.com/xuanan/p/7575809.html
Copyright © 2011-2022 走看看