简介

Model + Form ==> ModelForm。model和form的结合体,所以有以下功能:

  • 验证
  • 数据库操作

Form回顾

models.py

  1. class UserType(models.Model):
  2. caption = models.CharField(max_length=32)
  3.  
  4. class UserInfo(models.Model):
  5. username = models.CharField(max_length=32)
  6. email = models.EmailField()
  7. user_type = models.ForeignKey(to='UserType',to_field='id')

forms.py

  1. from django import forms
  2. from django.forms import fields
  3.  
  4. class UserInfoForm(forms.Form):
  5. # username = models.CharField(max_length=32) <-- models
  6. username = fields.CharField(max_length=32)
  7. # email = models.EmailField() <-- models
  8. email = fields.EmailField()
  9. # user_type = models.ForeignKey(to='UserType',to_field='id') <-- models
  10. user_type = fields.ChoiceField(
  11. choices=models.UserType.objects.values_list('id','caption')
  12. )
  13.  
  14. # 下面的操作是让数据在网页上实时更新。
  15. def __init__(self, *args, **kwargs):
  16. super(UserInfoForm,self).__init__(*args, **kwargs)
  17. self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')

index.html

  1. <body>
  2. <form action="/index/" method="POST" novalidate="novalidate">
  3. {% csrf_token %}
  4. {{ obj.as_p }}
  5. <input type="submit" value="提交">
  6. </form>
  7. </body>

  从上面的小例子能看出,models的字段和forms的字段大部分都是重复的,所以,django给我们提供了一种更为简洁的ModelFrom

ModelForm的用法

forms.py

  1. class UserInfoModelForm(forms.ModelForm):
  2.  
  3. class Meta:
  4. model = models.UserInfo # 与models建立了依赖关系
  5. fields = "__all__"

views.py

  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. print(obj.is_valid()) # 这是方法,别忘记了加括号
  8. print(obj.cleaned_data)
  9. print(obj.errors)
  10. return render(request,"index.html",{'obj':obj})

index.html

  1. <body>
  2. <form action="/index/" method="POST" novalidate="novalidate">
  3. {% csrf_token %}
  4. {{ obj.as_p }}
  5. <input type="submit" value="提交">
  6. </form>
  7. </body>

ModelForm常见参数

自定义字段名(html显示的字段)

如何定义http上定义的字段呢,自定义写成中文的?之前的用法是在Form里写上label。Model Form定义要用verbose_name

指定显示那些字段

  1. class UserInfo(models.Model):
  2. username = models.CharField(max_length=32, verbose_name='用户')
  3. email = models.EmailField(verbose_name='邮箱')
  4. user_type = models.ForeignKey(to='UserType',to_field='id', verbose_name='类型')

如果不在model里定义,在modelForm里实现,利用labels

  1. class UserInfoModelForm(forms.ModelForm):
  2.  
  3. class Meta:
  4. model = models.UserInfo
  5. fields = "__all__"
  6. labels = {
  7. 'username':'用户名',
  8. 'email':'邮箱',
  9. }

指定需要展示的字段

fields = "__all__"上面展示所有的,也可以展示指定的列

  1. fields = ['username','email'] # 显示指定列
  2. exclude = ['username'] # 排除指定列

错误信息

  1. error_messages = {
  2. '__all__':{ # 整体错误信息
  3.  
  4. },
  5. 'email': {
  6. 'required': '邮箱不能为空',
  7. 'invalid': '邮箱格式错误..',
  8. }
  9. }

给字段添加css属性

  1. widgets = {
  2. 'username': Fwidgets.Textarea(attrs={'class': 'c1'})
  3. }

ModelForm的验证

跟form一样,ModleForm里面也有is_validcleaned_dataerrors

  1. # Form验证:
  2. UserInfoForm -> Form -> BaseForm( 包含is_valid等方法)
  3.  
  4. # ModelForm验证:
  5. UserInfoModelForm -> ModelForm -> BaseModelForm -> BaseForm

ModelForm对数据库操作

添加数据

如果数据验证通过,直接调用save()方法,django会自动往数据库里添加一条数据(会根据modles里的字段一一对应)

  1. if obj.is_valid():
  2. obj.save() # 创建数据

如果在如下一对多、多对多关系中,如:

  1. class UserType(models.Model):
  2. caption = models.CharField(max_length=32)
  3.  
  4. class UserGroup(models.Model):
  5. name = models.CharField(max_length=32)
  6.  
  7. class UserInfo(models.Model):
  8. username = models.CharField(max_length=32)
  9. email = models.EmailField()
  10. user_type = models.ForeignKey(to='UserType',to_field='id')
  11. u2g = models.ManyToManyField(UserGroup)

这样的话,执行上面的obj.save()会自动在UserInfo表和多对多关系表里都增加数据,灰常灰常方便。

  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. obj.save() # 等价以下三句
  9. # instance = obj.save(False)
  10. # instance.save()
  11. # obj.save_m2m()
  12. return render(request,'index.html',{'obj': obj})

修改数据

修改表数据是,记得把instance信息也传进去,如:mf = UserInfoModelForm(request.POST,instance=user_obj)

不然是新建数据,而不是对某行数据进行修改。

编辑用户信息,新url方式保留默认数据

urls.py

  1. url(r'^user_list/', views.user_list),
  2. url(r'^edit-(\d+)/', views.user_edit),

views.py

  1. def user_list(request):
  2. li = models.UserInfo.objects.all().select_related('user_type') # 这里只能是外键,多对多字段也不可以
  3. return render(request,'user_list.html',{'li': li})
  4.  
  5. def user_edit(request, nid):
  6. # 获取当前id对象的用户信息
  7. # 显示用户已经存在数据
  8. if request.method == "GET":
  9. user_obj = models.UserInfo.objects.filter(id=nid).first()
  10. mf = UserInfoModelForm(instance=user_obj) # 把默认数据传递进去
  11. return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
  12. elif request.method == 'POST':
  13. # 数据修改的信息,给数据库的哪一行做修改?
  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})

user_list.html

  1. <body>
  2. <ul>
  3. {% for row in li %}
  4. <li>{{ row.username }} - {{ row.user_type.caption }} - <a href="/edit-{{ row.id }}/">编辑</a></li>
  5. {% endfor %}
  6. </ul>
  7. </body>

user_edit.html

  1. <body>
  2. <form method="POST" action="/edit-{{ nid }}/">
  3. {% csrf_token %}
  4. {{ mf.as_p }}
  5. <input type="submit" value="提交" />
  6. </form>
  7. </body>

  

Django之ModelForm的更多相关文章

  1. Django中ModelForm应用

    Django中ModelForm的应用 在传统中Form提交的POST的数据在服务器端获取时将不得不一一获取并验证数据的可靠性,但是使用django提供的Form时可简化该过程并提供相应的验证,同时D ...

  2. Django的ModelForm

    基于django.forms.ModelForm:与模型类绑定的Form 先定义一个ModelForm类,继承ModelForm类 from django.forms import ModelForm ...

  3. Django中Model-Form验证

    Django中Model-Form验证 class UserType(models.Model): caption=models.CharField(max_length=32) class User ...

  4. django中ModelForm save方法 以及快速生成空表单或包含数据的表单 包含错误信息

    django中ModelForm学习系列一~save方法 Model代码 from django.db import models # Create your models here. class P ...

  5. Django 四——ModelForm用法

    内容概要: 1.新增数据库表中数据 2.更新数据库表中数据 Django的ModelForm Django中内置了Form和Model两个类,有时候页面的表单form类与Model类是一一对应,因此分 ...

  6. Django(十四)课程机构列表页数据展示,Django的modelform,关于urls的重新分发

    关于urls的重新分发: 如果所有url都配置在根路径的urls.py里,会特别多,而且也不易于修改,Django框架里支持urls的重新分发: 1.在根路径的urls配置上: PS:namespac ...

  7. 【Django】--ModelForm组件

    ModelForm a.class Meta: model,#对应Model的 fields=None,#字段 exclude=None,#排除字段 labels=None,#提示信息 help_te ...

  8. Django的ModelForm组件

    创建类 from django.forms import ModelForm from django.forms import widgets as wd from app01 import mode ...

  9. Django之modelform组件

    一.简介与基本使用 简介:django中的modelform组件同时具有model和form作用,但是耦合度比较高,当项目需要拆分时候就比较困难了,所以在使用modelform时候需要先考虑项目的扩展 ...

  10. 【django之modelform】

    一.什么是modelform ModelForm顾名思义就Form和Django的Model数据库模型结合体,可以简单.方便得对数据库进行增加.编辑操作和验证标签的生成: 举例说明: 比如我们的数据库 ...

随机推荐

  1. FFmpeg的H.264解码器源代码简单分析:概述

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  2. 1073. Scientific Notation (20)

    题目如下: Scientific notation is the way that scientists easily handle very large numbers or very small ...

  3. (NO.00004)iOS实现打砖块游戏(六):反弹棒类

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 打砖块游戏另一个要素是反弹棒,我们在这篇类来实现反弹棒类. 创建 ...

  4. 基于xml 实现动态加载权限功能树列表---EFSFrame企业级开发架构

    在学习EFSFrame框架的过程中,感触最深的就是通过xml来实现前台与后台数据的交互,页面设计灵活,不用管后台如何写的,前台与后台的交互唯一的交互通道都是xml,在我们需要添加页面.添加规定的格式的 ...

  5. Android光线传感器-android学习之旅(65)

    主要讲解光线传感器的使用,其实所有的传感器用法类似 主要是定义一个TextView用来显示光线强度,用完了以后记得在OnDestory里面释放资源 代码如下 public class MainActi ...

  6. 01_Weblogic课程之概念篇:代理服务器,web服务器,应用程序服务器,JNDI概念,JTA概念,Java消息服务,Java验证和授权(JAAS),Java管理扩展,Web客户机,客户机应用程序

     1 什么是服务器 Weblogic中服务器分为两种,一种是受管服务器,另外一种是管理服务器. Weblogic课程(Weblogic是Oracle公司的,最开始的是BEA公司的) 一 系统管理 ...

  7. 有关Spring注解@xxx的零碎知识

     在Java的Spring开发中经常使用一些注解,例如 @XXX 等等,在网上看到收集整理碎片知识,便于懒人计划^=^... 过去,Spring使用的Java Bean对象必须在配置文件[一般为a ...

  8. 【Android 应用开发】Android 图表绘制 achartengine 示例解析

    作者 : 韩曙亮 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/38420197 一. AChartEngine 简介 1. 项 ...

  9. DQM Serial Sync Index Program ERROR

    Error syncing hz_stage_party_sites_t1:ORA-20000:Oracle Text 错误: DRG-10502:索引AR.HZ_STAGE_PARTY_SITES_ ...

  10. JSP 对象的作用范围

    在JSP中,对象有四种范围:page.request.session和application page范围             所谓的page范围指单一的JSP页面范围,page范围内的对象只能在 ...