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的更多相关文章
- Django中ModelForm应用
Django中ModelForm的应用 在传统中Form提交的POST的数据在服务器端获取时将不得不一一获取并验证数据的可靠性,但是使用django提供的Form时可简化该过程并提供相应的验证,同时D ...
- Django的ModelForm
基于django.forms.ModelForm:与模型类绑定的Form 先定义一个ModelForm类,继承ModelForm类 from django.forms import ModelForm ...
- Django中Model-Form验证
Django中Model-Form验证 class UserType(models.Model): caption=models.CharField(max_length=32) class User ...
- django中ModelForm save方法 以及快速生成空表单或包含数据的表单 包含错误信息
django中ModelForm学习系列一~save方法 Model代码 from django.db import models # Create your models here. class P ...
- Django 四——ModelForm用法
内容概要: 1.新增数据库表中数据 2.更新数据库表中数据 Django的ModelForm Django中内置了Form和Model两个类,有时候页面的表单form类与Model类是一一对应,因此分 ...
- Django(十四)课程机构列表页数据展示,Django的modelform,关于urls的重新分发
关于urls的重新分发: 如果所有url都配置在根路径的urls.py里,会特别多,而且也不易于修改,Django框架里支持urls的重新分发: 1.在根路径的urls配置上: PS:namespac ...
- 【Django】--ModelForm组件
ModelForm a.class Meta: model,#对应Model的 fields=None,#字段 exclude=None,#排除字段 labels=None,#提示信息 help_te ...
- Django的ModelForm组件
创建类 from django.forms import ModelForm from django.forms import widgets as wd from app01 import mode ...
- Django之modelform组件
一.简介与基本使用 简介:django中的modelform组件同时具有model和form作用,但是耦合度比较高,当项目需要拆分时候就比较困难了,所以在使用modelform时候需要先考虑项目的扩展 ...
- 【django之modelform】
一.什么是modelform ModelForm顾名思义就Form和Django的Model数据库模型结合体,可以简单.方便得对数据库进行增加.编辑操作和验证标签的生成: 举例说明: 比如我们的数据库 ...
随机推荐
- 13 SQLiteOpenHelper SQLiteDatabase详解
创建数据库: 1. 创建一个类继承SQLiteOpenHelper 2. 创建继承对象 new SQLiteOpenHelper() 3. 用创建的对象获取可写或者可读的SQLiteDatabase ...
- wincvs的“License for this product has expired”问题解决
新入职的公司代码管理工具是CVS,使用wincvs作为客户端工具.今天发现执行login.logout.update等操作的时候总是报"License for this product ha ...
- 2、Android构建本地单元测试
如果你的单元测试在Android中没有依赖或者只有简单的以来,你可以在你的本地开发环境中运行你的测试.这种测试比较高效因为它能让你避免将整个app安装到物理设备或虚拟机中执行单元测试.最后,执行单元测 ...
- boost::coroutine 无法显示调用栈
boost::coroutine 无法显示调用栈(金庆的专栏)一例因 boost::format() 格式化参数个数错误造成的 coredump,因为使用了 boost::coroutine, 无法显 ...
- Ubuntu 12.04: How to enable root login
1. vi /etc/lightdm/lightdm.conf and add following modifications. greeter-show-manual-login=true allo ...
- RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇 ...
- Unable to handle 'index' format version '2', please update rosdistro的解决办法
之前安装的ROS是Fuerte版本的,好久没有更新,不知不觉又出来了好几个新的版本,今天删除了Fuerte,计划安装Hydro版本的尝尝新,按照官网的安装流程,很快就可以把新版本安装上去了,但是在&q ...
- JSON 的数据转换格式(DataTable或DataSet) -善良公社项目
这两天在使用JqueryEasyUI框架绑定数据并实现自动分页时,由于框架的限制需要使用Json数据的来传递与获取数据: JSON的全称是JavaScript Object Notation, 是一种 ...
- ios swift 实现饼状图进度条,swift环形进度条
ios swift 实现饼状图进度条 // // ProgressControl.swift // L02MyProgressControl // // Created by plter on 7/2 ...
- 海量数据挖掘MMDS week4: 推荐系统之数据降维Dimensionality Reduction
http://blog.csdn.net/pipisorry/article/details/49231919 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...