一、复用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解密的更多相关文章

  1. Flask-session,WTForms,POOL,Websocket通讯原理 -握手,加密解密过程

    1.Flask-session Flask中的session 需要执行 session_interface - open_session存储到redis中,存的key:session:d3f07db2 ...

  2. PHP的学习--RSA加密解密

    PHP服务端与客户端交互或者提供开放API时,通常需要对敏感的数据进行加密,这时候rsa非对称加密就能派上用处了. 举个通俗易懂的例子,假设我们再登录一个网站,发送账号和密码,请求被拦截了. 密码没加 ...

  3. ASP.NET加密和解密数据库连接字符串

    大家知道,在应用程序中进行数据库操作需要连接字符串,而如果没有连接字符串,我们就无法在应用程序中完成检索数据,创建数据等一系列的数据库操作.当有人想要获取你程序中的数据库信息,他首先看到的可能会是We ...

  4. 微信小程序之用户数据解密(七)

    [未经作者本人同意,请勿以任何形式转载] 经常看到有点的小伙伴在群里问小程序用户数据解密流程,所以打算写一篇关于小程序用户敏感数据解密教程: 加密过程微信服务器完成,解密过程在小程序和自身服务器完成, ...

  5. 【腾讯Bugly干货分享】Android动态布局入门及NinePatchChunk解密

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7ff5d53bbcffd68c64411 作者:黄进——QQ音乐团队 摆脱 ...

  6. ASP.NET OAuth:access token的加密解密,client secret与refresh token的生成

    在 ASP.NET OWIN OAuth(Microsoft.Owin.Security.OAuth)中,access token 的默认加密方法是: 1) System.Security.Crypt ...

  7. Chrome浏览器Cookie解密

    做过 web 开发的都知道:浏览器会把重要的认证登录认证信息存放到 cookie 中,在 cookie 有效期内,再次访问这个网站的时候就可以直接从 cookie 中获取到登录信息,这样就可以实现自动 ...

  8. C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密

    在上篇随笔<C#开发微信门户及应用(19)-微信企业号的消息发送(文本.图片.文件.语音.视频.图文消息等)>介绍了有关企业号的消息发送,官方特别声明消息是不用加密发送的.但是在回调的服务 ...

  9. 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输

    Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...

随机推荐

  1. 连接Mysql错误 error 1042 can't get hostname for your address

    背景: 1.etc下的hosts文件有:     127.0.0.1   localhost 2.MySQL的my.ini配置文件:     [mysqld] 节点下已经加入以下两行代码 skip-n ...

  2. 你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧

    最近Jerry在忙一个项目,技术栈换成了nodejs平台,语言换成了JavaScript,因为赶项目进度,一直没时间更新公众号.感谢大家的支持,关注人数还是慢慢地增长到了3000. 今天我们来聊聊一个 ...

  3. Mina使用总结(二)Handler

    Handler的基本作用,处理接收到的客户端信息 一个简单的Handler实现如下: package com.bypay.mina.handler; import java.util.Date; im ...

  4. 如何动态调用 C 函数

    JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtensi ...

  5. 4719: [Noip2016]天天爱跑步

    Time Limit: 40 Sec Memory Limit: 512 MB Submit: 1986 Solved: 752 [Submit][Status][Discuss] Descripti ...

  6. PHP MemCached高级缓存配置图文教程

    memcache是一个高性能的分布式的内存对象缓存系统,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等.     1.Memcache相关介绍 memcache是一个高性能的 ...

  7. vue2.* 事件结合双向数据绑定、模块化以及封装Storage实现todolist 待办事项 已经完成 和进行中持久化 06

    ceshi.vue <template> <div id="app"> <input type='text' v-model='todo' @keyd ...

  8. ES6新特性6:模块Module

    本文摘自ECMAScript6入门,转载请注明出处. 一.Module简介 ES6的Class只是面向对象编程的语法糖,升级了ES5的构造函数的原型链继承的写法,并没有解决模块化问题.Module功能 ...

  9. Java反射学习四

    利用反射调用私有方法.访问私有属性 利用反射,首先是Class对象的获取,之后是Method和Field对象的获取. 以Method为例,从文档中可以看到: getMethod()方法返回的是publ ...

  10. Visual Studio 2012 编译错误【error C4996: 'scanf': This function or variable may be unsafe. 】的解决方案

    在VS 2012 中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may ...