Django—ModelForm
简介
Model + Form ==> ModelForm。model和form的结合体,所以有以下功能:
- 验证
- 数据库操作
Form回顾
models.py
class UserType(models.Model):
caption = 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')
forms.py
from django import forms
from django.forms import fields class UserInfoForm(forms.Form):
# username = models.CharField(max_length=32) <-- models
username = fields.CharField(max_length=32)
# email = models.EmailField() <-- models
email = fields.EmailField()
# user_type = models.ForeignKey(to='UserType',to_field='id') <-- models
user_type = fields.ChoiceField(
choices=models.UserType.objects.values_list('id','caption')
) # 下面的操作是让数据在网页上实时更新。
def __init__(self, *args, **kwargs):
super(UserInfoForm,self).__init__(*args, **kwargs)
self.fields['user_type'].choices = models.UserType.objects.values_list('id','caption')
index.html
<body>
<form action="/index/" method="POST" novalidate="novalidate">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit" value="提交">
</form>
</body>
从上面的小例子能看出,models的字段和forms的字段大部分都是重复的,所以,django给我们提供了一种更为简洁的ModelFrom
ModelForm的用法
forms.py
class UserInfoModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo # 与models建立了依赖关系
fields = "__all__"
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)
print(obj.is_valid()) # 这是方法,别忘记了加括号
print(obj.cleaned_data)
print(obj.errors)
return render(request,"index.html",{'obj':obj})
index.html
<body>
<form action="/index/" method="POST" novalidate="novalidate">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit" value="提交">
</form>
</body>
ModelForm常见参数
自定义字段名(html显示的字段)
如何定义http上定义的字段呢,自定义写成中文的?之前的用法是在Form里写上label。Model Form定义要用verbose_name
指定显示那些字段
class UserInfo(models.Model):
username = models.CharField(max_length=32, verbose_name='用户')
email = models.EmailField(verbose_name='邮箱')
user_type = models.ForeignKey(to='UserType',to_field='id', verbose_name='类型')
如果不在model里定义,在modelForm里实现,利用labels
class UserInfoModelForm(forms.ModelForm):
class Meta:
model = models.UserInfo
fields = "__all__"
labels = {
'username':'用户名',
'email':'邮箱',
}
指定需要展示的字段
fields = "__all__"上面展示所有的,也可以展示指定的列
fields = ['username','email'] # 显示指定列
exclude = ['username'] # 排除指定列
错误信息
error_messages = {
'__all__':{ # 整体错误信息
},
'email': {
'required': '邮箱不能为空',
'invalid': '邮箱格式错误..',
}
}
给字段添加css属性
widgets = {
'username': Fwidgets.Textarea(attrs={'class': 'c1'})
}
ModelForm的验证
跟form一样,ModleForm里面也有is_valid,cleaned_data,errors,
# Form验证:
UserInfoForm -> Form -> BaseForm( 包含is_valid等方法) # ModelForm验证:
UserInfoModelForm -> ModelForm -> BaseModelForm -> BaseForm
ModelForm对数据库操作
添加数据
如果数据验证通过,直接调用save()方法,django会自动往数据库里添加一条数据(会根据modles里的字段一一对应)
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表和多对多关系表里都增加数据,灰常灰常方便。
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() # 等价以下三句
# instance = obj.save(False)
# instance.save()
# obj.save_m2m()
return render(request,'index.html',{'obj': obj})
修改数据
修改表数据是,记得把instance信息也传进去,如:mf = UserInfoModelForm(request.POST,instance=user_obj)
不然是新建数据,而不是对某行数据进行修改。
编辑用户信息,新url方式保留默认数据
urls.py
url(r'^user_list/', views.user_list),
url(r'^edit-(\d+)/', views.user_edit),
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>
Django—ModelForm的更多相关文章
- python 全栈开发,Day110(django ModelForm,客户管理之 编辑权限(一))
昨日内容回顾 1. 简述权限管理的实现原理. 粒度控制到按钮级别的权限控制 - 用户登陆成功之后,将权限和菜单信息放入session - 每次请求时,在中间件中做权限校验 - inclusion_ta ...
- 【python】-- Django ModelForm
Django ModelForm Django的ModelForm的验证方式相比较form + Model的验证方式有下列区别: ModelForm没有form + Model的低耦合性 ModelF ...
- django modelform中的self.instance
在stackoverflow上看到一个问题,正好是我疑惑很久的相关问题. [原问题地址]https://stackoverflow.com/questions/18265023/self-instan ...
- 关于Django ModelForm渲染时间格式问题
关于Django ModelForm渲染时间格式问题 直接定义DateTimeInput或者DateTimeFile是不行的,渲染在html页面中的仍然是Input text类型 解决办法:自定义小部 ...
- Django ModelForm and Form
django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm 关于django的表单系统,主要分两种 基于django.forms.Form 基于dj ...
- django Modelform
前言: 为什么要用form去验证呢? 我们提交的是form表单,在看前端源码时如果检查到POST URL及我们提交的字段,如果没有验证我们是否可以直接POST数据到URL,后台并没有进行校验,直接处理 ...
- Django ModelForm修改默认的控件属性
Django 中利用ModelForm 可以快速地利用数据库对应的Model 子类来自动创建对应表单. 例如: from django.db import models from django.for ...
- 33.Django ModelForm
ModelForm 1.ModeForm简单验证 from django.db import models # Create your models here. class UserInfo(mode ...
- 10.Django ModelForm
ModelForm 1.ModeForm简单验证 from django.db import models # Create your models here. class UserInfo(mode ...
- Django ModelForm 校验数据格式
发现ModelForm很好用,用来做form表单验证效果很好.但是也要注意几点. forms的用法: 使用默认方式:继承forms.Form类,类里面的字段名称一定要和前端HTML里面的form表单里 ...
随机推荐
- echarts之title-textAlign
option: { title : { text: '各类数据采集总量TOP5', subtext: '', x:'center', y:'top', textAlign:'center' },}
- 大话编程:非常有趣的循环(Python语言可视化海龟画图演示)
在日常工作和生活中,我们经常会遇到一件事情要重复做很多次的这种情况发生.在编程中,我们也会遇到这种情况,循环这种机制,就是专门用来处理这种需要不断重复做的事情的方法.通过几分钟的阅读,你将会掌握这种机 ...
- EasyNetQ使用(一)【介绍】
EasyNetQ 是一个容易使用,专门针对RabbitMQ的 .NET API. 假如你尽可能快的想去安装和运行RabbitMQ,请去看入门指南.EasyNetQ是为了提供一个尽可能简洁的适用与Rab ...
- 事理学神器PDCA
做事情都按PDCA循环来做,基本就是一个靠谱的人. 这个方法论其实也符合架构师的思维中的分治理论.把大事拆分成一件件小事,并把小事做好. Plan Do Check Action
- HTML-T
a标签跳转 <a href="new_link" target="_blank">在新建页面打开链接</a>. <a href=& ...
- 324rfwrtg5gft8oywtfbserkufgs
324rfwrtg5gft8oywtfbserkufgs (tester.inf.nano)
- 【ARM-Linux开发】wayland和weston的介绍
简单地说,Wayland是一套display server(Wayland compositor)与client间的通信协议,而Weston是Wayland compositor的参考实现.其官网为h ...
- 【VS开发】千兆以太网的传输速度
千兆以太网主流标准 千兆以太网络技术早在上世纪90年代末就已成熟,其中,1995年国际标准化组织TIA/EIA颁布了1000Base-TX标准,该标准的目的是把双绞线用于千兆以太网中,其目的是在6类非 ...
- 洛谷 题解 P1352 【没有上司的舞会】
树形DP的一道较为基础的模板题 状态 dp[i][0/1]为第i个员工是否来参加的最大值 转移 先找到根节点 先遍历完它的儿子,再来更新答案 dp[i][0]+=max(dp[j][0],dp[j][ ...
- 【转帖】Linux的NUMA机制
Linux的NUMA机制 http://www.litrin.net/2014/06/18/linux的numa机制/ NUMA(Non-Uniform Memory Access)字面直译为“非一致 ...