Python开发【Django】:ModelForm操作
ModelForm
内容回顾:
Model
- 数据库操作
- 验证
class A(MOdel):
user =
email =
pwd =
Form
class LoginForm(Form):
email = fields.EmailField()
user =
pwd =
- is_valid -> 每一个字段进行正则(字段内置正则) + clean_字段 -> clean(__all__) -> _post_clean
- cleand_data
- error
--------> 推荐 <--------- 1、Model操作 创建数据表
操作数据库表
数据验证(弱)
2、Form操作 数据验证(强大)
3、ModelForm 数据库操作
数据验证
适合小程序,特别方便
自定制
缺点:ModelForm的耦合性非常强,数据库操作和验证操作代码都放到一块,项目大了的话,代码无法分离;建议以后写程序Model和Form分开写
内容回顾
1、ModelForm简单验证
其他文件:
from django.db import models # Create your models here. class UserInfo(models.Model):
# verbose_name 等同于Form类里面的label
username = models.CharField(verbose_name='用户',max_length=32)
email = models.EmailField(verbose_name='邮件')
user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id') class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self): #打印名称,不写显示的是obj对象
return self.caption
models.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/index/" method="post">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit" value="提交"/>
</form> </body>
</html>
index.html
ModelForm文件:
from django import forms
from django.forms import fields
from app import models class UserInfoModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo #去UserInfo类中获取数据
fields = '__all__' #__all__ 代指所有字段
# fields = ['username','email'] #指定显示的字段
# exclude = ['username'] #不显示的字段
处理文件:
from django.shortcuts import render
def index(request):
if request.method == 'GET':
obj = UserInfoModelForm()
return render(request,'index.html',{'obj':obj})
elif request.method == 'POST':
obj = UserInfoModelForm(request.POST)
result = obj.is_valid()
if result:
print(obj.cleaned_data) #如果models里没有__str__方法,则user_type获取
#到的是一个对象,可直接根据对象进行操作
print(obj.cleaned_data['user_type'])
# {'username': 'James', 'user_type': < UserType: 超级用户 >, 'email': 'ffd@fdsf.com'}
# 超级用户
else:
print(obj.errors)
return render(request,'index.html',{'obj':obj})
注:ModelForm最终继承了BaseForm,BaseForm里面具有is_valid方法,所以ModelForm也可以用is_valid进行验证
2、ModelForm组件
ModelForm
a. class Meta:
model, # 对应Model的
fields=None, # 字段
exclude=None, # 排除字段
labels=None, # 提示信息 labels ={'username':'用户名'}可写多个
help_texts=None, # 帮助提示信息 help_texts = {'username':'help info'}
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所有组件
① 自定义插件widgets:
from django.forms import widgets as Fwidgets #避免跟widgets重名
class UserInfoModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo #去UserInfo类中获取数据
fields = '__all__' #__all__ 代指所有字段
labels ={'username':'用户名'}
help_texts = {'username':'...'}
widgets = {
'username':Fwidgets.Textarea(attrs={'class':'c1'})
}
② 错误信息error_messages:
from django.forms import widgets as Fwidgets #避免跟widgets重名
class UserInfoModelForm(forms.ModelForm):
class Meta:
---snip---
error_messages = {
'__all__':{}, #整体的错误信息
'email':{'required':'邮箱不能为空'}
}
③ 自定义更改字段验证规则field_classes:
from django.forms import fields as Ffields #避免跟fields重名
class UserInfoModelForm(forms.ModelForm):
class Meta:
---snip---
field_classes ={
'email':Ffields.URLField #把邮件格式改为url格式验证
}
3、 ModelForm创建数据
其他文件:
from django.db import models # Create your models here. class UserInfo(models.Model):
# verbose_name 等同于Form类里面的label
username = models.CharField(verbose_name='用户',max_length=32)
email = models.EmailField(verbose_name='邮件')
user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
user_group = models.ManyToManyField('UserGroup') class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self): #打印名称,不写显示的是obj对象
return self.caption class UserGroup(models.Model):
groupname = models.CharField(max_length=32) def __str__(self): #打印名称,不写显示的是obj对象
return self.groupname
models.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/index/" method="post">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit" value="提交"/>
</form> </body>
</html>
index.html
from django import forms
from app import models
from django.forms import widgets as Fwidgets #避免跟widgets重名
from django.forms import fields as Ffields #避免跟fields重名
class UserInfoModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo #去UserInfo类中获取数据
fields = '__all__' #__all__ 代指所有字段
labels ={'username':'用户名'}
help_texts = {'username':'...'}
widgets = {
'username':Fwidgets.Textarea(attrs={'class':'c1'})
}
error_messages = {
'__all__':{}, #整体的错误信息
'email':{'required':'邮箱不能为空'}
}
ModelForm验证
处理文件:
from django.shortcuts import render
def index(request):
if request.method == 'GET':
obj = UserInfoModelForm()
return render(request,'index.html',{'obj':obj})
elif request.method == 'POST':
obj = UserInfoModelForm(request.POST)
if obj.is_valid():
# 验证成功直接保存
obj.save() #默认commit=True,会保存多对多
# 保存一对多表单
# instance = obj.save(commit=False)
# instance.save()
# 保存多对多数据
# obj.save_m2m()
return render(request,'index.html',{'obj':obj})
4、ModelForm更新和初始化
描述:打开用户列表,显示用户信息,点击编辑跳转到编辑页面,Input显示选择用户的当前值;提交后,对数据进行更新
其他文件:
from django.conf.urls import url
from django.contrib import admin
from app import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/$', views.index),
url(r'^list/$', views.user_list),
url(r'^edit-(\d+)', views.user_edit),
]
urls.py
from django.db import models # Create your models here. class UserInfo(models.Model):
# verbose_name 等同于Form类里面的label
username = models.CharField(verbose_name='用户',max_length=32)
email = models.EmailField(verbose_name='邮件')
user_type = models.ForeignKey(verbose_name='类型',to='UserType',to_field='id')
user_group = models.ManyToManyField('UserGroup') class UserType(models.Model):
caption = models.CharField(max_length=32) def __str__(self): #打印名称,不写显示的是obj对象
return self.caption class UserGroup(models.Model):
groupname = models.CharField(max_length=32) def __str__(self): #打印名称,不写显示的是obj对象
return self.groupname
models.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
{% for row in list %}
<p>{{ row.username }}--{{ row.user_type.caption }}--<a href="/edit-{{ row.id }}">编辑</a></p>
{% endfor %}
</ul>
</body>
</html>
user_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/edit-{{ nid }}" method="post">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit" value="提交" />
</form> </body>
</html>
user_edit.html
处理文件:
from django.shortcuts import render
from django import forms
from app import models class UserInfoModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo #去UserInfo类中获取数据
fields = '__all__' #__all__ 代指所有字段
labels ={'username':'用户名'}
help_texts = {'username':'...'} def user_list(request):
if request.method == 'GET':
list = models.UserInfo.objects.all().select_related('user_type')
return render(request,'user_list.html',{'list':list}) def user_edit(request,nid):
if request.method == 'GET':
user_obj = models.UserInfo.objects.filter(id=nid).first()
obj = UserInfoModelForm(instance=user_obj) # instance显示user_obj的对应值
return render(request, 'user_eidt.html', {'obj': obj,'nid':nid})
elif request.method == 'POST':
user_obj = models.UserInfo.objects.filter(id=nid).first()
obj = UserInfoModelForm(request.POST,instance=user_obj) #instance更新user_obj而不是添加
if obj.is_valid():
# 验证成功直接更新
obj.save()
else:
print(obj.errors.as_json())
return render(request, 'user_eidt.html', {'obj': obj,'nid':nid})
5、ModelForm钩子
ModelForm继承了is_valid方法,所以跟Form里的钩子用法一毛一样
class UserInfoModelForm(forms.ModelForm):
class Meta:
---snip---
def clean_username(self):
pass
生成额外的标签:
class UserInfoModelForm(forms.ModelForm):
# 生成额外的标签 选择框
is_rmb = fields.CharField(widget=Fwidgets.CheckboxInput())
class Meta:
---snip---
《第二十四章》
Python开发【Django】:ModelForm操作的更多相关文章
- 【python】-- Django ModelForm
Django ModelForm Django的ModelForm的验证方式相比较form + Model的验证方式有下列区别: ModelForm没有form + Model的低耦合性 ModelF ...
- Django ModelForm操作及验证
一.内容回顾 Model - 数据库操作 - 验证 class A(MOdel): user = email = pwd = Form - class LoginForm(Form): email = ...
- python开发_tkinter_图片操作
在java的swing中,我们可以找到一些有关图片的操作,对于python的tkinter类似,也有对于图片的相关操作 下面是我做的demo 运行效果: ======================= ...
- python开发_python日期操作
在python中对日期进行操作的库有: import datetime import time 对日期格式化信息,可以参考官方API: time.strftime datetime 下面是我做的dem ...
- python开发_python文件操作
关于python文件操作的详细说明,大家可以参考:关于python的文件操作 官方API:os-Miscellaneous operating system interfaces 下面是我做的demo ...
- Python开发——6.文件操作
一.文件操作 1.文件操作的处理流程 打开文件得到文件句柄并赋值给一个变量====>通过句柄对文件进行分析====>关闭文件 #1. 打开文件,得到文件句柄并赋值给一个变量 f=open( ...
- python 全栈开发,Day110(django ModelForm,客户管理之 编辑权限(一))
昨日内容回顾 1. 简述权限管理的实现原理. 粒度控制到按钮级别的权限控制 - 用户登陆成功之后,将权限和菜单信息放入session - 每次请求时,在中间件中做权限校验 - inclusion_ta ...
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- Python开发【第二十一篇】:Web框架之Django【基础】
Python开发[第二十一篇]:Web框架之Django[基础] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5237704.html Python之 ...
- django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用
一.modelForm操作及验证 1.获取数据库数据,界面展示数据并且获取前端提交的数据,并动态显示select框中的数据 views.py from django.shortcuts import ...
随机推荐
- Spring-bean的作用域
在大多数情况下,单例bean是很理想的方案.初始化和垃圾回收对象实例所带来的的成本只留给一些小规模任务,在这些任务中,让对象保持无状态并且在应用中反复重用这些对象可能并不合理.在这种情况下,将clas ...
- Storm-源码分析-Streaming Grouping (backtype.storm.daemon.executor)
executor在发送outbounding message的时候, 需要决定发送到next component的哪些tasks 这里就需要用到streaming grouping, 1. mk- ...
- ScrollView:ScrollView can host only one direct child异常
java.lang.IllegalStateException: ScrollView can host only one direct child 原因是在外面有一个TextView控件,将其删除则 ...
- thinkphp nginx+phpcgj安装配置
环境:mysql-5.6.26 nginx-1.9.4.tar.gz php-5.6.13 程序框架ThinkPHP 客户要求必须使用nginx + php 1.首先安装n ...
- SQL基础--视图
视图其实就是一条查询SQL语句,用于显示一个或多个表或其它视图中相关数据. 创建视图: CREATE [OR REPLACE] [FORCE |NOFORCE ]VIEW view_name [al ...
- WPS之替换样式
以前写文档需要颜色设置什么的时候,都是遇到的时候,就进行设置,挺烦的,要一直切换. 今天突然想到,既然有替换应该可能也有样式替换,就查了一下,试了试果然可以,以后就这么干了
- MQTT-SN协议乱翻之实现要点
前言 本篇是MQTT-SN 1.2协议最后一篇翻译了,主要涉及实现要点,很简短. 需要支持QoS 值为 -1 QoS虽默认设置有0,1,2三个值,但还有一种情况其值为-1.来自客户端的PUBLISH消 ...
- JS-提取字符串—>>普通方法VS正则表达式
如下:“23nr qreq2 34fq4 4454gsr 45” [将这一串字符中的数字挑出来,当然人家作伴的不能被分开]. 一.普通方法: <script type="text/ja ...
- Centos7 安装zabbix3.0 服务端 详细
参考: https://www.cnblogs.com/37yan/p/6879218.html http://blog.csdn.net/hao134838/article/details/5712 ...
- Fluent Nhibernate Mapping for Sql Views
Views are mapped the same way tables are mapped except that you should put Readonly() in the mapping ...