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数据库模型结合体,可以简单.方便得对数据库进行增加.编辑操作和验证标签的生成: 举例说明: 比如我们的数据库 ...
随机推荐
- XML之DTD(文档类型定义)
文档类型定义(DTD)可定义合法的XML文档构建模块.它使用一系列合法的元素来定义文档的结构. DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用. 声明元素 在 DTD 中,XML 元素 ...
- ubuntu权限管理常用命令
1.chmod 第一种方式 chomd [{ugoa}{+-=}{rwx}] [文件或者目录] u 代表该文件所属用户 g 代表该文件所属用户组 o 代表访客 a 代表所有用户 +-=分别表示增加权限 ...
- 【一天一道LeetCode】#113. Path Sum II
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- Android学习之AppWidget高级效果
接着AppWidget基础学习,今天是一个"进阶版"的小例子,用来检验一下自己的学习效果.于是就做了一个掷骰子的Widget. 方便大家观看,先截图如下: 需要注意的是在drawa ...
- Android PackageManager源码浅析以及静默安装实现方式
Aandroid应用管理 >http://blog.csdn.net/sk719887916/article/details/50314017 skay整理. >201 ...
- 利用openssl管理证书及SSL编程第1部分: openssl证书管理
利用openssl管理证书及SSL编程第1部分 参考:1) 利用openssl创建一个简单的CAhttp://www.cppblog.com/flyonok/archive/2010/10/30/13 ...
- C++ Primer 有感(异常处理)(三)
先看下面的代码: [cpp] view plaincopy int main() { int *i=new int(10); /* 这中间的代码出现异常 */ delete i; return 0; ...
- 【Android 应用开发】 ActionBar 基础
作者 : 万境绝尘 (octopus_truth@163.com) 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/3920439 ...
- 海量数据挖掘MMDS week4: 推荐系统Recommendation System
http://blog.csdn.net/pipisorry/article/details/49205589 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...
- Leetcode_119_Pascal's Triangle II
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41851069 Given an index k, retu ...