ModelForm适用于前台验证和后台直接操作数据库的前后台未做分离,可以一次执行验证和保存数据的场景。

注意:  1.  ModelForm里面没有删除方法,需要手动删除内容

2. ModelForm里面也可以像Form里面一样自定义clean_email()和clean()方法进行数据正确性的验证【post_clean()方法需要自定义try...except

ModelForm创建信息

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('modelFormDemo/', views.modelFormDemo),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# ModelForm实例
from django import forms as modelForm
from app01 import models
class UserModelForm(modelForm.ModelForm):
# 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据
class Meta:
# 说明指向,指定去执行U里面的内容
model = models.U
# 指定类中的字段,告诉ModelForm帮我们处理多少字段
fields = '__all__' # 这里是帮我们处理所有字段 def modelFormDemo(request):
if request.method == "GET":
obj = UserModelForm()
return render(request, 'modelFormDemo.html', {"obj":obj})
else :
obj = UserModelForm(request.POST)
if obj.is_valid():
data = obj.clean()
print('正确数据:', data)
# 这个是以前我们Model操作来进行增加数据:models.U.objects.create(**data)
obj.save() # 这个是ModelForm直接帮我们添加数据,同样也适用于多对多的情况
err = obj.errors
print('错误数据:', err)
return render(request, 'modelFormDemo.html', {"obj":obj})

templates/modelFormDemo.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
{#as_p是从BaseForm里面的方法#}
<form action="/modelFormDemo/" method="POST">
{{ obj.as_p }}
<input type="submit" value="提交">
</form>
</body>
</html>

models.py

from django.db import models
class U(models.Model):
id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系] class UT(models.Model):
caption = models.CharField(max_length=32)
def __str__(self):
return self.caption

页面显示;

初始化数据库

python manage.py makemigrations
python manage.py migrate

ModelForm之实时更新下拉框数据

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('edit_UserModelForm-(\d+)/', fm.edit_UserModelForm),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# ModelForm实例
from django import forms as modelForm
class UserModelForm(modelForm.ModelForm):
# 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据
class Meta:
# 说明指向,指定去执行U里面的内容
model = models.U
# 指定类中的字段,告诉ModelForm帮我们处理多少字段
fields = '__all__' # 这里是帮我们处理所有字段 # 修改ModelForm内容
def edit_UserModelForm(request, nid):
if request.method == "GET":
obj_model = models.U.objects.get(id=nid) # 后台数据库的数据
obj = UserModelForm(instance=obj_model) # 把数据库的数据给了ModelForm
return render(request, 'modelFormDemo.html', {"obj": obj}) # 进行页面显示
else:
obj_model = models.U.objects.get(id=nid) # 后台数据库的数据
# 如果有instance则修改,没有则添加新数据
obj = UserModelForm(request.POST, instance=obj_model) # 获取前台提交的数据进行更新操作
if obj.is_valid():
data = obj.clean()
print('正确数据:', data)
# 这个是以前我们Model操作来进行增加数据:models.U.objects.create(**data)
obj.save() # 这个是ModelForm直接帮我们添加数据,同样也适用于修改数据的情况
return render(request, 'edit_modelFormDemo.html', {"obj": obj, 'nid':nid}) # 进行页面显示

templates/edit_modelFormDemo.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
{#as_p是从BaseForm里面的方法#}
<form action="/edit_UserModelForm-{{ nid }}/ " method="POST">
{{ obj.as_p }}
<input type="submit" value="提交">
</form>
</body>
</html>

models.py

from django.db import models
class U(models.Model):
id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系] class UT(models.Model):
caption = models.CharField(max_length=32)
def __str__(self):
return self.caption

页面显示;

初始化数据库

python manage.py makemigrations
python manage.py migrate

ModelForm之save()方法分析

save()方法的集成度非常高,帮我们可以保存当前表的数据也可以保存多对多表的数据,一对多也是在当前表中,内部默认做了这些事

手动提交内容:

ModelForm之Meta的配置选项

ModelForm
a.class Meta:
model, # 对应Model的
fields = None, # 字段
exclude = None, # 排除字段
labels = None, # 提示信息
labels = {‘email’:‘邮箱’,’username’:’用户名’}
help_texts = None, # 帮助提示信息
widgets = None, # 自定义插件
error_messages = None, # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
field_classes = None # 自定义字段类 (也可以自定义字段)
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):
# 可以抛出异常
# 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={...}) 

# ModelForm实例

views.py

from django import forms as modelForm
from app01 import models
# 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据
class UserModelForm(modelForm.ModelForm):
# 相当于在Model中U类的基础上有新添加了一个字段,属自定制内容
# 如果有跟数据库内的字段重名了,则会覆盖数据库字段的验证功能[Email验证功能]
# email = forms.CharField() -->此时就是一个普通的char类型,遵循Form优先的原则
# 总结一下就是: 如果跟数据库不重名,则页面增加一条输入框;
# 如果重名,则会覆盖原来【Form优先】
# 适用于那种一个月自动登录功能。可以从用户处多拿一个字段到后台进行验证功能
pwd = forms.CharField() # 此时数据库内并无此字段,这里添加后页面会增加此字段
class Meta:
# 说明指向,指定去执行U里面的内容【只能指定一个Model类】
model = models.U
# 指定类中的字段,告诉ModelForm帮我们处理多少字段
fields = '__all__' # 这里是帮我们处理所有字段,包括多对多的数据
# fields = ['name', 'email'] # 处理某几个字段
# exclude = ['name'] # 排除username的页面显示
labels = {
'name': '用户名',
'email': '邮 箱'
}
help_texts = {
'email':"*",
'name':'请输入姓名'
}
# 自定义插件
from django.forms import widgets as ws
from django.forms import forms as ff
widgets = {
'email': ws.Textarea()
}
error_messages = {
'__all__':{‘required’:‘必填内容’},# 全局错误信息集
'name': {'required':'必填项', 'invalid':'格式错误'}
}
# 自定义字段类,进行二次验证
field_classes = {
'name': ff.EmailField # 虽然数据库时CharField,这里要求页面用EmailField进行正则验证
}

models.py

from django.db import models
class U(models.Model):
id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系]
class UT(models.Model):
caption = models.CharField(max_length=32)
def __str__(self):
return self.caption

ModelForm操作:http://www.cnblogs.com/wupeiqi/articles/6229414.html

Python学习---ModelForm拾遗180325的更多相关文章

  1. Python学习---Model拾遗[1]180318

    Model: 强大的数据库操作,弱小的数据验证 Form:  强大的数据验证 ModelForm: 强大的数据验证 + 弱小的数据库操作 Model拾遗 Model基本操作 1. 创建数据库表2. 修 ...

  2. Python学习---Form拾遗180322

    Form操作之错误信息操作 1. 用户发送请求过来 2. for 循环对字段进行正则表达式的验证  fields.clean(value) 3. 自定义clean_字段() 进行名字段值正确性的校验 ...

  3. Python学习---Model拾遗[2]180318

    Model的字段及字段参数: Model字段: 数字        字符串(带正则的字段)        时间        文件       特殊字段:(一对一,一对多,多对多) Models.py ...

  4. Python学习---Django拾遗180328

    Django之生命周期 前台发送URL请求到Django的中间件进行内容校验,完成校验后到达路由映射文件url.py,然后调用视图函数views.py里面的函数进行内容处理[ 1.操作数据库进行数据读 ...

  5. python学习博客地址集合。。。

    python学习博客地址集合...   老师讲课博客目录 http://www.bootcdn.cn/bootstrap/  bootstrap cdn在线地址 http://www.cnblogs. ...

  6. Python学习--04条件控制与循环结构

    Python学习--04条件控制与循环结构 条件控制 在Python程序中,用if语句实现条件控制. 语法格式: if <条件判断1>: <执行1> elif <条件判断 ...

  7. Python学习--01入门

    Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...

  8. Python 学习小结

    python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...

  9. Python学习路径及练手项目合集

    Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159

随机推荐

  1. php的isset()和empty()区别

    转载:http://www.cnblogs.com/ndxsdhy/archive/2011/04/02/2003193.html 1.isset()函数 一般用来检测变量是否设置 (是否已经赋值) ...

  2. java将list转为树形结构的方法

    目录 1.通过转化成json封装数据 2.通过java8 stream转换 1.通过转化成json封装数据 原始数据如下 [ { "name":"甘肃省", & ...

  3. java面试⑥框架部分

    2.5.1 什么是框架: 2.5.2 MVC模式 2.5.3 MVC框架 2.5.4 简单讲一下struts2的执行流程 2.5.5 Struts2中的拦截器,你都用它干什么? 2.5.6 简单讲一下 ...

  4. Keepalived配置与使用--转载

    作者: JeremyWei | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明 网址: http://weizhifeng.net/using-keepalived.html 介绍 ...

  5. 如何找出长时间未提交的事务session ID

    收到报警某台mysql数据库慢查询数量超过5,登录上去看,发现阻塞的SQL全部是update,处于Updating状态 +---------+------+-----------+------+--- ...

  6. [转]ASP.NET cache缓存的用法

    本文转自:https://blog.csdn.net/mss359681091/article/details/51076712 本文导读:在.NET运用中经常用到缓存(Cache)对象.有HttpC ...

  7. js 背景自动切换

    //首页自动更换背景特效开始============================================ var curIndex = 0; //时间间隔(单位毫秒),每秒钟显示一张,数组 ...

  8. 如何在HTML 5中拖动光标图标?

    window.app = { dragging: false, config: { canDrag: false, cursorOffsetX: null, cursorOffsetY: null } ...

  9. MyEclipse中设置代码块快捷键

    如果想用快捷键生成一段自定义代码,可以通过下面方式设置: Java->Editor->Templates->New 如果要设置或者更改某个快捷键,如要设置保存全部文档的快捷键(系统默 ...

  10. java并发编程的艺术(三)---lock源码

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...