ModelForm

在使用Model和Form时,都需要对字段进行定义并指定类型,通过ModelForm则可以省去From中字段的定义

应用场景:定制model admin 的时候可以使用。适用于小业务架构。

ModelForm
a. class Meta:
model, # 对应Model的
fields=None, # 字段
exclude=None, # 排除字段
labels=None, # 提示信息
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={...})

views.py

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo
fields = '__all__' # 请求处理
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})

models.py

class UserType(models.Model):
caption = models.CharField(max_length=32) class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to=UserType, to_field='id', on_delete=models.SET_NULL,null=True)

注:verbose_name 为django admin管理数据 的时候显示 的字段。在模板中渲染时,调用modelForm对象实例也可以显示对应的中文

{{ verify_obj.as_p }}
{{ verify_obj.as_ul }}
{{ verify_obj.as_table }}

modelForm.html
    <form action="/modelformtest/" method="post">
{% csrf_token %}
{{ verify_obj.as_p }}
<input type="submit" value="提交">
</form>

访问效果

-------------------------------------------------------------------------------------------------------------

只展示指定列 fields =

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo
# fields = '__all__'
fields = ['username', ]

排除指定列 :exclude = ['xxx',...]

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo
# fields = '__all__'
# fields = ['username', ]
exclude = ['username']

labels 效果等于models.py里面定义数据表字段时的 verbose_name='xxx'

为对输入字段自定义提示语

views.py

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
labels = { # 生成html标签的对应input标签前面的提示
'username': 'lables 用户名',
'email': '邮箱',
'user_type': '用户类型'
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
modelForm.html
    <form action="/modelformtest/" method="post">
{% csrf_token %}
{{ verify_obj.as_p }}
<input type="submit" value="提交">
</form>

------------------------------------------------------------------------

help_texts=None, # 帮助提示信息

views.py

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
help_texts = { # 提示信息
'username': '用户名哦',
'email': '邮箱啊'
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})

html

{{ verify_obj.as_p }}

--------------------------------------------------------------------

widgets=None, # 自定义标签类型插件

wiews.py

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
widgets = {
'username': forms_widgets.Textarea(attrs={'class': 'test-class'})
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj})

html

    <form action="/modelformtest/" method="post">
{% csrf_token %}
{{ verify_obj.as_p }}
<input type="submit" value="提交">
</form>

--------------------------------------------------------------------------------------------

error_messages = {'字段名': {'错误类型': '错误提示', ... }}

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
error_messages = {
'email': {
'required': '必填',
'invalid': '邮箱格式错误'
},
'username': {
'max_length': '太长了',
'min_length': '太短了',
}
}
class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj}) def post(self, request):
# 获取所有数据
# 每条数据请求的验证
# 成功显示正确信息
# 失败,给出错误提示
# 验证时将request.POST 传递给验证类,实例化验证对象
# verify_obj = MyFm(request.POST)
verify_obj = UserInfoModelForm(request.POST) verify_result = verify_obj.is_valid() # 验证是否通过,返回True/False
if not verify_result:
return render(request, 'modelForm.html', {'verify_obj': verify_obj})
# 整体错误信息使用 '__all__' 代表所有字段
error_messages = {
'__all__': {
'required': '必填',
'invalid': '格式错误'
},
}

生成html浏览器查看效果

-------------------------------------------

field_classes  更改原有字段生成的html标签类型

views.py

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
from django.forms import fields as form_fields
field_classes = {
'email':form_fields.URLField
}

-------------------------------------------------------------------------------------------------

localized_fields=('birth_date',)  # 将数据本地化显示,如:根据不同时区显示数据

前提:

  需要在settings.py中设置好本地的时区

# setting中的配置
TIME_ZONE = 'Asia/Shanghai' # 时区
USE_TZ = True # 启用本地时区

views.py

localized_fields=('birth_date',) # 本地化,如:根据不同时区显示数据
# 如数据库中存的 2016-12-27 04:10:57
# 则前端显示:2016-12-27 12:10:57

ModelForm 的数据库保存方式

验证有效,直接使用验证实例.save() 保存到数据库

  views.py

class ModelFormTest(View):
def get(self, request):
# ModelForm 创建对象
verify_obj = UserInfoModelForm()
return render(request, 'modelForm.html', {'verify_obj': verify_obj}) def post(self, request):
# 获取所有数据
# 每条数据请求的验证
# 成功显示正确信息
# 失败,给出错误提示
# 验证时将request.POST 传递给验证类,实例化验证对象
# verify_obj = MyFm(request.POST)
verify_obj = UserInfoModelForm(request.POST)
if verify_obj.is_valid():
# 默认保存多对多 :第三张表的数据
verify_obj.save()
# 不做任何操作,内部定义 save_m2m(用于保存多对多)
#verify_obj.save(commit=False)
#verify_obj.save() # 保存单张表信息
#verify_obj.save_m2m() # 保存关联多对多 第三张表的信息

models.py

数据表结构UserInfo UserType UserGroup

UserInfo ---> UserType  一对多

UserInfo<----> UserGroup 多对多

class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self):
return self.caption class UserGroup(models.Model):
name = models.CharField(max_length=32) class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to=UserType, to_field='id', on_delete=models.SET_NULL,null=True)
u_in_g = models.ManyToManyField(UserGroup)

-----------------------------------------------------------------------

应用案例:用户列表 查看/编辑用户信息,保存到数据库

models.py

UserInfo 表 user_type字段外键UserType id字段

UserInfo 表u_in_g 字段外键 多对多 UserGroup表id字段

from django.db import models

# Create your models here.

class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self):
return self.caption class UserGroup(models.Model):
name = models.CharField(max_length=32) def __str__(self):
return self.name class UserInfo(models.Model):
username = models.CharField(verbose_name='用户名', max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to=UserType, to_field='id', on_delete=models.SET_NULL,null=True)
u_in_g = models.ManyToManyField(UserGroup)

查已保存的数据信息展示给前端

ModelForm 指定instance 数据对象(自定义的数据表 具体的查询结果对象),可以显示给前端

例如:user_html_obj = UserInfoModelForm(instance=user_data)

更新数据库中的信息

  例如:

    user = models.UserInfo.objects.filter(id=uid).first()

    mf_obj = UserInfoModelForm(request.POST, instance=user)

    mf_obj.save()

    验证post请求的数据有效。更新到指定的查询结果中去,如果不指定instance 则为新增数据操作

views.py

class UserList(View):
def get(self, request):
users = models.UserInfo.objects.all().select_related('user_type')
return render(request, 'modelForm_user_lisst.html' , {'users': users}) class UserEdit(View):
def get(self, request, uid):
user_data = models.UserInfo.objects.filter(id=uid).first()
print('数据查询:', type(user_data))
# 将数据库查询出来的数据对象
user_html_obj = UserInfoModelForm(instance=user_data)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': user_html_obj, 'uid': uid})
pass def post(self, request,uid):
user = models.UserInfo.objects.filter(id=uid).first()
mf_obj = UserInfoModelForm(request.POST, instance=user)
# 更新的数据符合要求,保存到数据库
if mf_obj.is_valid():
mf_obj.save()
else:
print(mf_obj.errors.as_json)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': mf_obj, 'uid': uid})

modelForm的钩子

验证顺序:is_valid-->full_clean-->clean_fields-->clean_form-->_post_clean

1、在验证数据合法,保存到数据库之前,对验证的数据进行修改

定义 def clean_字段名():函数 对self.cleaned_data中获取到的字段进行修改

class UserInfoModelForm(forms.ModelForm):
class Meta(object):
#..................... def clean_username(self):
old_username = self.cleaned_data.get('username')
return old_username + '呵呵'

增加不存储于数据库的字段

应用场景:是否记住登录

views.py

from django.shortcuts import render
from django.views import View
from django import forms from modelForm_study import models
from django.forms import widgets as forms_widgets
# Create your views here. class UserInfoModelForm(forms.ModelForm): # 在生成前端标签的时候增加的字段(相比数据库表里面的字段)
rember_login = forms.CharField(
widget=forms_widgets.CheckboxInput(),
required=False # 是否必填
)
class Meta(object):
model = models.UserInfo # 从哪个models 数据表里面获取字段
fields = '__all__' # 展示哪些字段
from django.forms import fields as form_fields
# field_classes = { # 改变原有字段类型
# 'email':form_fields.URLField
# }
error_messages = {
'__all__': {
'required': '必填',
'invalid': '格式错误'
},
'email': {
'required': '必填',
'invalid': '邮箱格式错误'
},
'username': {
'max_length': '太长了',
'min_length': '太短了',
}
}
help_texts = { # 提示信息
'username': '用户名哦',
'email': '邮箱啊'
}
labels = { # 生成html标签的对应input标签前面的提示
'username': 'lables 用户名',
'email': '邮箱',
'user_type': '用户类型',
'u_in_g': '所在组',
}
# widgets = {
# 'username': forms_widgets.Textarea(attrs={'class': 'test-class'})
# }
# fields = ['username', ]
# exclude = ['username'] # def clean_username(self):
# old_username = self.cleaned_data.get('username')
# return old_username + '呵呵'
# 请求处理 class UserList(View):
def get(self, request):
users = models.UserInfo.objects.all().select_related('user_type')
return render(request, 'modelForm_user_lisst.html' , {'users': users}) class UserEdit(View):
def get(self, request, uid):
user_data = models.UserInfo.objects.filter(id=uid).first()
print('数据查询:', type(user_data))
# 将数据库查询出来的数据对象
user_html_obj = UserInfoModelForm(instance=user_data)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': user_html_obj, 'uid': uid})
pass def post(self, request,uid):
user = models.UserInfo.objects.filter(id=uid).first()
mf_obj = UserInfoModelForm(request.POST, instance=user)
# mf_obj = UserInfoModelForm(request.POST) # 更新的数据符合要求,保存到数据库
if mf_obj.is_valid():
print(mf_obj.cleaned_data)
mf_obj.save()
if mf_obj.cleaned_data.get('rember_login'):
# 记住登录用户xxx时间内免登陆,设置cookie ,session等
print('是否记住登录:', mf_obj.cleaned_data.get('rember_login'))
else:
print(mf_obj.errors.as_json)
return render(request, 'ModelForm_user_edit.html', {'user_html_obj': mf_obj, 'uid': uid})

Django ModelForm表单验证的更多相关文章

  1. python运维开发(十九)----Django后台表单验证、session、cookie、model操作

    内容目录: Django后台表单验证 CSRF加密传输 session.cookie model数据库操作 Django后台Form表单验证 Django中Form一般有2种功能: 1.用于做用户提交 ...

  2. django form表单验证

    一. django form表单验证引入 有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ; <!DOCTYPE html> <html ...

  3. django from表单验证

    django from表单验证   实现:表单验证 工程示例: urls.py 1 2 3 4 5 6 7 8 9 from django.conf.urls import url from djan ...

  4. Django(5) session登录注销、csrf及中间件自定义、django Form表单验证(非常好用)

    一.Django中默认支持Session,其内部提供了5种类型的Session供开发者使用: 数据库(默认) 缓存 文件 缓存+数据库 加密cookie 1.数据库Session 1 2 3 4 5 ...

  5. Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)

    通常验证用户输入是否合法的话,是前端js和后端共同验证的,这是因为前端js是可以被禁用的,假如被禁用了,那就没法用js实现验证合法与否了,也就是即使用户输入的不合法,但是也没提示,用户也不知道怎么输入 ...

  6. django book表单验证学习

    django提供了强大的表单验证功能form 个人认为是把html代码封装到form里面,就像封装models中的数据一样.而且带有强大的验证功能,不需要后台再去写一堆乱七八糟的验证 具体操作查看dj ...

  7. Django之表单验证

    对于前端的表单进行验证的方法,从最简单的js到基于XML传输的Ajax,再到cookie的免认证,现在Django为我们提供了自带的表单验证方法. views.py: from django impo ...

  8. 使用ModelForm表单验证

    1.定义model.py model中定义的字段类型,只有在通过form进行验证的时候才有效,数据库中的字段类型与其并不完全一致,如数据库中并没有ipaddress类型.如果不通过form对字段进行验 ...

  9. django form 表单验证

随机推荐

  1. 面向对象的程序设计之JS创建对象的9种模式及其优缺点

    目录 1.new Object () 2.字面式创建对象 3.工厂模式 4.构造函数模式 4.1.将构造函数当作函数 4.2.构造函数的问题 5.原型模式 5.1.理解原型对象 5.2.原型与in操作 ...

  2. 【2020五校联考NOIP #8】自闭

    题目传送门 题意: 有一个 \(n \times m\) 的矩阵,里面已经填好了 \(k\) 个非负整数. 问是否能在其它 \(n \times m-k\) 个格子里各填上一个非负整数,使得得到的矩阵 ...

  3. Codeforces 632F - Magic Matrix(暴力 bitset or Prim 求最小生成树+最小瓶颈路)

    题面传送门 开始挖老祖宗(ycx)留下来的东西.jpg 本来想水一道紫题作为 AC 的第 500 道紫题的,结果发现点开了道神题. 首先先讲一个我想出来的暴力做法.条件一和条件二直接扫一遍判断掉.先将 ...

  4. Codeforces 1270E - Divide Points(构造+奇偶性)

    Codeforces 题目传送门 & 洛谷题目传送门 显然,直接暴力枚举是不可能的. 考虑将点按横纵坐标奇偶性分组,记 \(S_{i,j}=\{t|x_t\equiv i\pmod{2},y_ ...

  5. TVB斜率限制器

    TVB斜率限制器 本文参考源程序来自Fluidity. 简介 TVB斜率限制器最早由Cockburn和Shu(1989)提出,主要特点是提出了修正minmod函数 \[\tilde{m}(a_1, a ...

  6. Browse Code Answers

    一个记录各种语言可能遇到的问题的论坛 :https://www.codegrepper.com/code-examples/

  7. Excel-给出指定数值的日期 date()

    DATE函数 函数名称:DATE 主要功能:给出指定数值的日期. 使用格式:DATE(year,month,day) 参数说明:year为指定的年份数值(小于9999):month为指定的月份数值(可 ...

  8. 前端2 — CSS — 更新完毕

    1.CSS是什么? 指:Cascading Style Sheet  --- 层叠样式表 CSS 即:美化网页( 在HTML不是说过W3C规定网页为三种标准嘛,结构层HTML已经玩了,而这个CSS就是 ...

  9. 学习java 7.16

    学习内容: 线程安全的类 Lock锁 生产者消费者模式 Object类的等待唤醒方法 明天内容: 网络编程 通信程序 遇到问题: 无

  10. 3步!完成WordPress博客迁移与重新部署

    本文来自于轻量应用服务器征文活动的用户投稿,已获得作者(昵称nstar)授权发布. 由于现有的服务器已经到期,并且活动已经取消,续费一个月145元比较贵,于是参加了阿里云的活动购买一台轻量应用服务器. ...