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. CF1418G Three Occurrences

    统计满足某些性质的区间个数. 我们考虑移动 \(r\) 指针. 然后考虑把不能选的区间 \(ban\)掉. 具体看下细节吧. #include<iostream> #include< ...

  2. 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)

    洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\)​​​​​.我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...

  3. Codeforces 983E - NN country(贪心+倍增优化)

    Codeforces 题面传送门 & 洛谷题面传送门 一道(绝对)偏简单的 D1E,但是我怕自己过若干年(大雾)忘了自己的解法了,所以过来水篇题解( 首先考虑怎么暴力地解决这个问题,不难发现我 ...

  4. 【机器学习与R语言】5-规则学习算法

    目录 1.分类规则原理 1.1 1R单规则算法 1.2 RIPPER算法 2. 规则学习应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估性能 5)提高性能 6)选择决策树中的分类规则 ...

  5. Markdown—.md文件是什么?怎么打开?

    md全称markdown,markdown也是一种标记语言. md文件其实可以用常用的文本编辑器都可以打开.   用记事本打开,把markdown文件拖到记事本图标上就可以打开 .   用 subli ...

  6. EXCEL-批量修改列宽

    WPS:先用鼠标选中一列,然后,长按ctrl键并且用鼠标选中剩余想要统一列宽的列,松开ctrl键,鼠标落在刚选中的任意一列的抬头上,鼠标右键,选择列宽,设置统一列宽即可.

  7. 使用 Skywalking 对 Kubernetes(K8s)中的微服务进行监控

    1. 概述 老话说的好:任何成功都不是轻易得来的,是不断地坚持与面对的结果. 言归正传,之前我们聊了 SpringCloud 开发的微服务是如何部署在  Kubernetes(K8s)集群中的,今天我 ...

  8. Vector总结及部分底层源码分析

    Vector总结及部分底层源码分析 1. Vector继承的抽象类和实现的接口 Vector类实现的接口 List接口:里面定义了List集合的基本接口,Vector进行了实现 RandomAcces ...

  9. Android editttext只能输入不能删除(选中后被软键盘遮住)

    感谢https://www.dutycode.com/post-20.html: 解决方法:在布局外外嵌一层scrollview.

  10. acid, acknowledge, acquaint

    acid sulphuric|hydrochloric|nitric|carbolic|citric|lactic|nucleic|amino acid: 硫|盐|硝|碳|柠檬|乳|核|氨基酸 王水是 ...