博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django之ModelForm组件
阅读量:5146 次
发布时间:2019-06-13

本文共 7607 字,大约阅读时间需要 25 分钟。

 

 一、创建一个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}} #主要是得到的是表中的哪个外键字段以及外键字段对应的数据,得到的是个类似于
的内存地址,只有是外键的字段才会显示出来{
{ 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 ModelFormfrom django.forms import widgets as widfrom django.forms import fields as fldclass 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或者就直接仅仅声明这个属性的时候,不会验证字段)

 

   

    

转载于:https://www.cnblogs.com/xuanan/p/7575809.html

你可能感兴趣的文章
[转自小龙博客]优酷视频自动播放办法
查看>>
深入理解事件捕获冒泡
查看>>
软件设计入门2 数据库设计
查看>>
文件信息
查看>>
Hibernate 一对一外键单向关联
查看>>
笔记1
查看>>
Link-cut-tree 学习记录 & hdu4010
查看>>
ECharts使用小结
查看>>
JAVA实现MD5加密算法(使用MessageDigest)
查看>>
壮哉大微软,.Net人的春天来了,你准备好了嘛!
查看>>
Spine学习五- spine动画融合
查看>>
Python科学计算工具包
查看>>
2-4 zookeeper配置文件介绍,运行zk
查看>>
00_前情回顾
查看>>
运行项目psychologicalTest
查看>>
pgrep,pkill
查看>>
filter-grok,dissect匹配数据
查看>>
java 排序3 插入排序
查看>>
旋转90度也可以,Lumia的四大重置方式
查看>>
服务器与服务器之间的链接测试
查看>>