Django的model form组件

扩展:Django 之Form组件

首先我们要知道 Model 和 Form 分别时干什么的

  • Model  生成表数据
  • Form  对表单、字段进行校验

Django的model form组件是一个神奇的组件,这个组件的功能就是把modelform组合起来;

用法:比如我们的数据库中有这样一张学生表,字段有姓名年龄爱好邮箱电话住址注册时间等等一大堆信息,现在让你写一个创建学生的页面,你的后台应该怎么写呢?

首先我们会在前端一个一个罗列出这些字段,让用户去填写,然后我们一个一个接收用户的输入,创建一个新的学生对象,保存;

其实,重点不是这些,而是合法性验证,我们需要在前端判断用户输入是否合法,比如姓名必须在多少字符以内,电话号码必须是多少位的数字,邮箱必须是邮箱的格式;

这些当然可以一点一点手动写限制,各种判断;除了繁琐,我们现在有个更优雅(以后在Python相关的内容里,要多用“优雅”这个词,并且养成习惯)的方法:

先简单把ModelForm用上,再来加验证条件。

创建modelform

  1. 首先导入ModelForm
  2.  
  3. from django.forms import ModelForm
  4. 在视图函数中,定义一个类,比如就叫StudentList,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,并注意首字母是大写的)
  5. 在这个原类中,有以下属性(部分):
  6.  
  7. class StudentList(ModelForm):
  8. class Meta:
  9. model = models.Student #对应的Model中的类
  10. fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
  11. exclude = None #排除的字段
  12. labels = None #提示信息
  13. help_texts = None #帮助提示信息
  14. widgets = None #自定义插件
  15. error_messages = None #自定义错误信息
  16. #error_messages用法:
  17. error_messages = {
  18. 'name':{'required':"用户名不能为空",},
  19. 'age':{'required':"年龄不能为空",},
  20. }
  21. #widgets用法,比如把输入用户名的input框给为Textarea
  22. #首先得导入模块
  23. from django.forms import widgets as wid #因为重名,所以起个别名
  24. widgets = {
  25. "name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性
  26. }
  27. #labels,自定义在前端显示的名字
  28.     labels= {
  29. "name":"用户名"
  30. }

然后在url对应的视图函数中实例化这个类,把这个对象传给前端

  1. def student(request):
  2.  
  3. if request.method == 'GET':
  4. student_list = StudentList()
  5. return render(request,'student.html',{'student_list':student_list})

然后前端只需要 {{ student_list.as_p }} 一下,所有的字段就都出来了,可以用as_p显示全部,也可以通过for循环这个

student_list,拿到的是一个个input框,现在我们就不用as_p,手动把这些input框搞出来,as_p拿到的页面太不美观。

首先 for循环这个student_list,拿到student对象,直接在前端打印这个student,是个input框student.label ,拿到数据库中每个字段的verbose_name ,如果没有设置这个属性,

拿到的默认就是字段名,还可以通过student.errors.0 拿到错误信息有了这些,我们就可以通过bootstrap,自己拼出来想要的样式了,比如:

  1. <body>
  2. <div class="container" >
  3. <h1>student</h1>
  4. <form method="POST" novalidate>
  5. {% csrf_token %}
  6. {# {{ student_list.as_p }}#}
  7. {% for student in student_list %}
  8. <div class="form-group col-md-6">
  9. {# 拿到数据字段的verbose_name,没有就默认显示字段名 #}
  10. <label class="col-md-3 control-label">{{ student.label }}</label>
  11. <div class="col-md-9" style="position: relative;">{{ student }}</div>
  12. </div>
  13. {% endfor %}
  14. <div class="col-md-2 col-md-offset-10">
  15. <input type="submit" value="提交" class="btn-primary">
  16. </div>
  17. </form>
  18. </div>
  19. </body>

现在还缺一个input框的form-contral样式,可以考虑在后台的widget里面添加
比如这样:

  1. from django.forms import widgets as wid #因为重名,所以起个别名
  2. widgets = {
  3. "name":wid.TextInput(attrs={'class':'form-control'}),
  4. "age":wid.NumberInput(attrs={'class':'form-control'}),
  5. "email":wid.EmailInput(attrs={'class':'form-control'})
  6. }

当然也可以在js中,找到所有的input框,加上这个样式,也行。

添加纪录

保存数据的时候,不用挨个取数据了,只需要save一下

  1. def student(request):
  2.  
  3. if request.method == 'GET':
  4. student_list = StudentList()
  5. return render(request,'student.html',{'student_list':student_list})
  6. else:
  7. student_list = StudentList(request.POST)
  8. if student_list.is_valid():
  9. student_list.save()
  10. return redirect(request,'student_list.html',{'student_list':student_list})

编辑数据

如果不用ModelForm,编辑的时候得显示之前的数据吧,还得挨个取一遍值,如果ModelForm,只需要加一个instance=obj(obj是要修改的数据库的一条数据的对象)就可以得到同样的效果
保存的时候要注意,一定要注意有这个对象(instance=obj),否则不知道更新哪一个数据
代码示例:

  1. from django.shortcuts import render,HttpResponse,redirect
  2. from django.forms import ModelForm
  3. # Create your views here.
  4. from app01 import models
  5. def test(request):
  6. # model_form = models.Student
  7. model_form = models.Student.objects.all()
  8. return render(request,'test.html',{'model_form':model_form})
  9.  
  10. class StudentList(ModelForm):
  11. class Meta:
  12. model = models.Student #对应的Model中的类
  13. fields = "__all__" #字段,如果是__all__,就是表示列出所有的字段
  14. exclude = None #排除的字段
  15. labels = None #提示信息
  16. help_texts = None #帮助提示信息
  17. widgets = None #自定义插件
  18. error_messages = None #自定义错误信息
  19. #error_messages用法:
  20. error_messages = {
  21. 'name':{'required':"用户名不能为空",},
  22. 'age':{'required':"年龄不能为空",},
  23. }
  24. #widgets用法,比如把输入用户名的input框给为Textarea
  25. #首先得导入模块
  26. from django.forms import widgets as wid #因为重名,所以起个别名
  27. widgets = {
  28. "name":wid.Textarea
  29. }
  30. #labels,自定义在前端显示的名字
  31. labels= {
  32. "name":"用户名"
  33. }
  34. def student(request):
  35. if request.method == 'GET':
  36. student_list = StudentList()
  37. return render(request,'student.html',{'student_list':student_list})
  38. else:
  39. student_list = StudentList(request.POST)
  40. if student_list.is_valid():
  41. student_list.save()
  42. return render(request,'student.html',{'student_list':student_list})
  43.  
  44. def student_edit(request,pk):
  45. obj = models.Student.objects.filter(pk=pk).first()
  46. if not obj:
  47. return redirect('test')
  48. if request.method == "GET":
  49. student_list = StudentList(instance=obj)
  50. return render(request,'student_edit.html',{'student_list':student_list})
  51. else:
  52. student_list = StudentList(request.POST,instance=obj)
  53. if student_list.is_valid():
  54. student_list.save()
  55. return render(request,'student_edit.html',{'student_list':student_list})

代码示例

总结:

  从上边可以看到ModelForm用起来是非常方便的,比如增加修改之类的操作。但是也带来额外不好的地方,model和form之间耦合度过高(高内聚低耦合)

  如果不耦合的话,mf.save()方法也无法直接提交保存。 但是耦合的话使用场景通常局限用于小程序,写大程序就最好不用了。

 
 

Django 之 ModelForm 组件的更多相关文章

  1. Django之modelform组件

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

  2. 【Django】--ModelForm组件

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

  3. Django的ModelForm组件

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

  4. 框架----Django之ModelForm组件

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

  5. 6月28日 Django form组件 和 modelform组件

    Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否 ...

  6. Django 之Form组件

    Django之From组件 扩展:Django 之 ModelForm组件 Form组件功能 Django的Form主要具有一下几大功能 生成HTML标签 验证用户数据(显示错误信息) HTML Fo ...

  7. django中forms和modelform组件的区别

    首先,我们来看看modelform的实现 model.py class Book(models.Model): title=models.CharField(max_length=32) price= ...

  8. Django之Form、ModelForm 组件

    Django之Form.ModelForm 组件 一.Form组件: django框架提供了一个form类,来处理web开发中的表单相关事项.众所周知,form最常做的是对用户输入的内容进行验证,为此 ...

  9. {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm

    Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...

随机推荐

  1. osx中Grapher的使用

    Grapher 是一个可创建方程图形的应用程序,因此您能够使结果可视化.您能够输入各种数学函数,以二维和三维图形方式查看它们. 您甚至能够让图形动起来.用图形制作影片文件. 打开osx中的Graphe ...

  2. Linux Barrier I/O 实现分析与barrier内存屏蔽 总结

    一直以来.I/O顺序问题一直困扰着我.事实上这个问题是一个比較综合的问题,它涉及的层次比較多,从VFS page cache到I/O调度算法,从i/o子系统到存储外设.而Linux I/O barri ...

  3. Solidworks如何在装配图中保存单独的一个零件

    如下图所示,我想要保存装配体的一个单独的零部件   选中该零件后点击编辑零部件   然后点击顶部的文件-另存为,弹出"解决模糊情形"对话框,询问你要保存装配体还是零部件   点击确 ...

  4. Visual Studio 外请版本号管理插件 - AnkhSVN

    Visual Studio 外请版本号管理插件 - AnkhSVN 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致 ...

  5. JAVA静态导入(inport static)详解

    在Java 5中,import语句得到了增强,以便提供甚至更加强大的减少击键次数功能,虽然一些人争议说这是以可读性为代价的.这种新的特性成为静态导入. 当你想使用static成员时,可以使用静态导入( ...

  6. cdn日志统一下载程序

    最近实现了网宿cdn,阿里云cdn,腾讯cdn的日志统一格式下载程序,使用简单方便,有需要详见代码: https://github.com/mikeluwen/CdnLogDownload

  7. 利用$(window).resize()实现窗口大小自适应宽度问题

    © 版权声明:本文为博主原创文章,转载请注明出处 问题描述:利用iframe做页面引入,用$(window).resize()作自适应:结果窗口变小时,利用$(window).width()获取到的宽 ...

  8. 如何验证cname,MX,spf记录是否生效?

    创建域名邮箱时,对域名做完相应设置后,在域名邮箱设置里点击“设置完成并提交验证”来等待验证所有权和MX记录设置的正确性.但同时也可以通过下面的方法确认设置是否成功和正确: 一.验证CNAME记录的方法 ...

  9. EasyUI datagrid border处理,加边框,去边框,都能够

    以下是EasyUI 官网上处理datagrid border的demo: 主要是这句: $('#dg').datagrid('getPanel').removeClass('lines-both li ...

  10. Android OOM的解决方式

    尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图. 由于这些函数在完毕decode后,终于都是通过ja ...