ModelForm解密
一、复用model表和字段
models.py文件
class User(models.Model):
username = models.CharField(max_length=32)
email = models.EmailField(max_length=32)
#指定关系一对多,指定哪张表,指定哪个字段
user_type = models.ForeignKey(to='UserType',to_field='id') class Meta:
unique_together = (('username','email'))
forms.py文件
class UserModelForm(forms.ModelForm):
class Meta:
model = models.User
fields = "__all__"
model指定哪个model类
fields = "__all__",指定展示所有列,也可以选定或排除对应的列
fields = ['username','email'] # 显示指定列
exclude = ['username'] # 排除指定列
views.py文件
def mf(request):
if request.method == 'GET':
obj = UserModelForm()
new_obj = models.User.objects.all()
return render(request,'index.html',{'obj':obj,'new_obj':new_obj})
elif request.method == 'POST':
obj = UserModelForm(request.POST)
if obj.is_valid():
obj.save()
return render(request,'index.html',{'obj':obj})
form里面有is_valid
,cleaned_data
,errors
index.html
<!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> <table>
<th>
<tr>用户名</tr>
<tr>邮箱</tr>
<tr>角色</tr>
</th>
{% for obj in new_obj %}
<tr>
<td>{{ obj.username }}</td>
<td>{{ obj.email }}</td>
<td>{{ obj.user_type.caption }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
二、实施
1、Meta和操作
a. class Meta:
model, # 对应Model的
fields=None, # form里面展示的字段
exclude=None, # form从models排除的字段
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. 用于更新和初始化,指定instance为更新记录
obj = model.tb.objects.get(id=1)
model_form_obj = XXOOModelForm(request.POST,instance=obj)
... PS: 单纯初始化
model_form_obj = XXOOModelForm(initial={...})
2、范例
注意:导入模块名(fields、widgets)和字段名重复,所以导入时要起个别名。
from django import forms
from django.forms import fields as Ffields
from django.forms import widgets as Fwidgets
class UserInfoModelForm(forms.ModelForm): is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput()) class Meta:
model = models.UserInfo
fields = '__all__'
# fields = ['username','email']
# exclude = ['username']
labels = {
'username': '用户名',
'email': '邮箱',
}
help_texts = {
'username': '...'
}
widgets = {
'username': Fwidgets.Textarea(attrs={'class': 'c1'})
}
error_messages = {
'__all__':{ # 整体错误信息 },
'email': {
'required': '邮箱不能为空',
'invalid': '邮箱格式错误..',
}
}
field_classes = { # 定义字段的类是什么
# 'email': Ffields.URLField # 这里只能填类,加上括号就是对象了。
} # localized_fields=('ctime',) # 哪些字段做本地化
三、数据库操作
1、创建数据save
如果数据验证是ok的,那么save,就直接在数据库中创建完数据了
if obj.is_valid():
obj.save() # 创建数据
在如下一对多、多对多关系中:
class UserType(models.Model):
caption = models.CharField(max_length=32) class UserGroup(models.Model):
name = models.CharField(max_length=32) class UserInfo(models.Model):
username = models.CharField(max_length=32)
email = models.EmailField()
user_type = models.ForeignKey(to='UserType',to_field='id')
u2g = models.ManyToManyField(UserGroup)
这样的话,执行上面的obj.save()
会在UserInfo表和多对多关系表里都增加数据。
views.py
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})
save()函数做了如下操作:
def save(self, commit=True):
""""""
if commit:
self.instance.save() # 指的当前model对象
self._save_m2m() # 指:保存m2m对象
else:
self.save_m2m = self._save_m2m
return self.instance # model 类的对象
""""""
所以instance = obj.save(False)
时,什么都不会操作。
if obj.is_valid():
instance = obj.save(commit=False)
instance.save() # 当前对象表数据创建
obj.save_m2m() # 多对多表数据创建
# 上面这三句完成的是和上面 obj.save 一样的操作。拆开就可以自定制操作了
2、修改数据
修改表数据是,记得把instance
信息也传进去,不然是新建数据,而不是对某行数据进行修改。
views.py
def user_list(request):
li = models.UserInfo.objects.all().select_related('user_type') # 这里只能是外键,多对多字段也不可以
return render(request,'user_list.html',{'li': li}) def user_edit(request, nid):
# 获取当前id对象的用户信息
# 显示用户已经存在数据
if request.method == "GET":
user_obj = models.UserInfo.objects.filter(id=nid).first()
mf = UserInfoModelForm(instance=user_obj) # 把默认数据传递进去,回显数据
return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
elif request.method == 'POST':
# 数据修改的信息,给数据库的哪一行做修改?
user_obj = models.UserInfo.objects.filter(id=nid).first()
mf = UserInfoModelForm(request.POST,instance=user_obj) # 指定修改哪条记录
if mf.is_valid():
mf.save()
else:
print(mf.errors.as_json())
return render(request,'user_edit.html',{'mf': mf, 'nid': nid})
user_list.html
<body>
<ul>
{% for row in li %}
<li>{{ row.username }} - {{ row.user_type.caption }} - <a href="/edit-{{ row.id }}/">编辑</a></li>
{% endfor %}
</ul>
</body>
user_edit.html
<body>
<form method="POST" action="/edit-{{ nid }}/">
{% csrf_token %}
{{ mf.as_p }}
<input type="submit" value="提交" />
</form>
</body>
五、继承关系
1、继承
UserModelForm==>ModelForm==>BaseModelForm==>BaseForm
UserInfoForm==>Form==>BaseForm
2、方法
1、ModelForm方法
class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)):
pass
2、BaseModelForm方法
3、BaseForm方法
六、总结
ModelForm适用于较小的工程中,耦合度较高,而当工程一旦变得很大时,Model和Form就需要分开,耦合度就会变低,更加灵活定制。
ModelForm解密的更多相关文章
- Flask-session,WTForms,POOL,Websocket通讯原理 -握手,加密解密过程
1.Flask-session Flask中的session 需要执行 session_interface - open_session存储到redis中,存的key:session:d3f07db2 ...
- PHP的学习--RSA加密解密
PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...
- ASP.NET加密和解密数据库连接字符串
大家知道,在应用程序中进行数据库操作需要连接字符串,而如果没有连接字符串,我们就无法在应用程序中完成检索数据,创建数据等一系列的数据库操作.当有人想要获取你程序中的数据库信息,他首先看到的可能会是We ...
- 微信小程序之用户数据解密(七)
[未经作者本人同意,请勿以任何形式转载] 经常看到有点的小伙伴在群里问小程序用户数据解密流程,所以打算写一篇关于小程序用户敏感数据解密教程: 加密过程微信服务器完成,解密过程在小程序和自身服务器完成, ...
- 【腾讯Bugly干货分享】Android动态布局入门及NinePatchChunk解密
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7ff5d53bbcffd68c64411 作者:黄进——QQ音乐团队 摆脱 ...
- ASP.NET OAuth:access token的加密解密,client secret与refresh token的生成
在 ASP.NET OWIN OAuth(Microsoft.Owin.Security.OAuth)中,access token 的默认加密方法是: 1) System.Security.Crypt ...
- Chrome浏览器Cookie解密
做过 web 开发的都知道:浏览器会把重要的认证登录认证信息存放到 cookie 中,在 cookie 有效期内,再次访问这个网站的时候就可以直接从 cookie 中获取到登录信息,这样就可以实现自动 ...
- C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密
在上篇随笔<C#开发微信门户及应用(19)-微信企业号的消息发送(文本.图片.文件.语音.视频.图文消息等)>介绍了有关企业号的消息发送,官方特别声明消息是不用加密发送的.但是在回调的服务 ...
- 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输
Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...
随机推荐
- USMT
备份当前用户状态:scanstate /i:miguser.xml /i:migapp.xml /i:migdocs.xml /config:config.xml c:\migstorefolder ...
- T-SQL 标识符
在T-SQL语言中,对SQLServer数据库及其数据对象(比如表.索引.视图.存储过程.触发器等)需要以名称来进行命名并加以区分,这些名称就称为标识符. 通常情况下,SQLServer数据库.数据库 ...
- React onPaste 获取粘贴板的值
React 中, 获取 粘贴板的值, 使用下面的方法 console.log(e.clipboardData.getData('Text')); 如果是 JS 中的 onpaste 事件, 则使用 v ...
- python队列
先入先出队列: import queue q = queue.Queue(10) # 10为队列长度 for i in range(5): q.put(i, block=False) # block= ...
- 【原创】MySQL 生产环境备份还原
公司需要对生产环境的数据库进行备份,我接下了这份任务. 1. 首先谷歌了以下大家的备份方法 许多都使用到了Xtrabackup这个工具,超大型的公司可能有其他的的备份方法,这个工具对于中小型公司,甚至 ...
- CSS3动画理解与应用
CSS3动画理解与应用 Transform:对元素进行变形:Transition:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画.但只有两个关键贞.开始,结束.Anima ...
- React & TypeScript
之前看了一下 TypeScript 的知识,但是一直没有上手,最近开始结合 React 和 TypeScript 一起尝试了一下,感受还是很好的,所以写一下笔记. 环境配置没有参考其他东西,就是看了下 ...
- loj6119 「2017 山东二轮集训 Day7」国王
题目描述 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当这条路径上的工 ...
- springMVC參数传递
本文是本人在学习网络视屏springMVC的过程中的学习笔记. 为了更便于理解我决定从实际使用的角度解释. 我们在浏览器输入地址 http://localhost:8080/springMVC6/us ...
- Codeforces 1133 F2. Spanning Tree with One Fixed Degree 并查集+生成树
好久没更新博客了,一直懒得动,这次更新一下. 题意大概是:给出一个图,求它的一个一号节点的度数恰好为D的生成树的方案. 一开始随便水了个乱搞贪心,不出意外并没有过. 仔细思考之后,对于这个问题我们可以 ...