Django之modelform组件
时间:2019-12-16
本文章向大家介绍Django之modelform组件,主要包括Django之modelform组件使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1. ModelForm的基本用法示例:
from django import forms
from app01 import models
class BookModelForm(forms.ModelForm):
class Meta:
# 告诉Django这个form类和那个model类对应
model = models.Book
# 告诉Django这个form类里面有哪些字段
fields = "__all__"
widgets = {
"publish_date": forms.widgets.DateInput(
# 给日期字段添加日期类型
attrs={"type": "date"}
)
}
labels = {
"title": "书名",
"price": "价格",
"publish_date": '出版日期',
"publisher": "出版社名称",
"authors": "作者"
}
error_messages = {
"title": {
"required": "书名不能为空"
}
}
# 通过修改类的初始化方法达到批量添加共同属性的目的
def __init__(self, *args, **kwargs):
super(BookModelForm, self).__init__(*args, **kwargs)
# for field_name in self.base_fields:
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
'class': 'form-control'
})
2. ModelForm所有属性:
class Meta:
model, # 对应Model的
fields=None, # 字段
exclude=None, # 排除字段
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',) # 本地化,如:根据不同时区显示数据
3. ModelForm用于验证用户数据:is_valid()
model_form_obj = XXOOModelForm() //实例化对象
model_form_obj.is_valid() // 校验数据
model_form_obj.errors.as_json() //错误
model_form_obj.clean() //同Form组件中的属性
model_form_obj.cleaned_data // 同Form组件中的属性
4. ModelForm用于创建数据:save()
def add_book(request):
if request.method == "POST":
#直接传request.POST,进行ModelForm的实例化传参
form_obj = forms.BookModelForm(request.POST)
if form_obj.is_valid(): # 校验数据
form_obj.save() #直接就可以保存数据到数据库,包括多对多,多对一,一对一的关系
return redirect("/book_list/")
#ModelForm实例化对象
form_obj = forms.BookModelForm()
return render(request, "v2/add_book.html", locals())
5. ModelForm用于初始化:ModelForm(instance=model_obj)
def edit_book(request, pk):
book_obj = models.Book.objects.filter(id=pk).first()
#form_obj通过initial设置初始化的值,例如,图书管理系统中的编辑书籍功能,
#点击编辑后跳转到编辑书籍页面,跳转后需要用要编辑的书籍信息填充页面对应信息。
#不同于Form组件的是,ModelForm直接就可以传实例化的对象,而不需要将对象转化成字典的形式传。
form_obj = forms.BookModelForm(instance=book_obj)
return render(request, "v2/edit_book.html", locals())
6. ModelForm用于更新 :ModelForm(request.POST, instance=book_obj)
def edit_book(request, pk):
book_obj = models.Book.objects.filter(id=pk).first()
if request.method == "POST":
#修改数据时,直接可以将用户数据包request.POST传进去,
#再传一个要修改的对象的示例,ModelForm就可以自动完成修改数据了。
form_obj = forms.BookModelForm(request.POST, instance=book_obj)
if form_obj.is_valid(): // 数据校验
form_obj.save() // 直接保存
return redirect("/book_list/")
#form_obj通过initial设置初始化的值,例如,图书管理系统中的编辑书籍功能,
#点击编辑后跳转到编辑书籍页面,跳转后需要用要编辑的书籍信息填充页面对应信息。
#不同于Form组件的是,ModelForm直接就可以传实例化的对象,而不需要将对象转化成字典的形式传。
form_obj = forms.BookModelForm(instance=book_obj)
return render(request, "v2/edit_book.html", locals())
7. ModelForm和Form组件的应用场景:
- ModelForm ---- 中小型应用程序。因为ModelForm是依赖于models的。
- Form ------- 大型应用程序
8. 通过ModelForm实现的书籍、作者、出版社的管理代码示例:
- 表结构:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=12)
address = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=12)
gender = models.SmallIntegerField(
choices=((0, '女'), (1, '男'), (2, '保密'))
)
age = models.IntegerField()
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2) # 0~999.99
publish_date = models.DateField()
publisher = models.ForeignKey(to="Publisher", on_delete=models.CASCADE)
authors = models.ManyToManyField(to="Author")
def __str__(self):
return self.title
- ModelForm类:
from django import forms
from app01 import models
class BookModelForm(forms.ModelForm):
class Meta:
# 告诉Django这个form类和那个model类对应
model = models.Book
# 告诉Django这个form类里面有哪些字段
fields = "__all__"
widgets = {
"publish_date": forms.widgets.DateInput(
# 给日期字段添加日期类型
attrs={"type": "date"}
)
}
labels = {
"title": "书名",
"price": "价格",
"publish_date": '出版日期',
"publisher": "出版社名称",
"authors": "作者"
}
error_messages = {
"title": {
"required": "书名不能为空"
}
}
# 通过修改类的初始化方法达到批量添加共同属性的目的
def __init__(self, *args, **kwargs):
super(BookModelForm, self).__init__(*args, **kwargs)
# for field_name in self.base_fields:
for field_name in iter(self.fields):
field = self.base_fields[field_name]
field.widget.attrs.update({
"class": "form-control",
})
- views 视图函数:
from django.shortcuts import render,redirect
from app01 import modelform
from app01 import models
def book_list(request):
book_list = models.Book.objects.all()
return render(request, 'book_list.html', {'book_list': book_list})
def add_book(request):
if request.method == "POST":
# modelform 直接可以将从前端拿到的数据组request.POST
#当参数传给实例化的Modelform
form_obj = modelform.BookModelForm(request.POST)
# 调用is_valid()方法校验数据
if form_obj.is_valid():
# 直接保存到数据库中
form_obj.save()
return redirect("/book_list/")
modelform_obj = modelform.BookModelForm()
return render(request, 'add_book.html', {"modelform_obj": modelform_obj})
def edit_book(request,pk):
book_obj = models.Book.objects.filter(id=pk).first()
if request.method == "POST":
#修改数据时,直接可以将用户数据包request.POST传进去,
#再传一个要修改的对象的示例,ModelForm就可以自动完成修改数据了。
form_obj = modelform.BookModelForm(request.POST, instance=book_obj)
if form_obj.is_valid():
form_obj.save()
return redirect("/book_list/")
# form_obj通过initial设置初始化的值,例如,图书管理系统中的编辑书籍功能,
# 点击编辑后跳转到编辑书籍页面,跳转后需要用要编辑的书籍信息填充页面对应信息。
# 不同于Form组件的是,ModelForm直接就可以传实例化的对象,而不需要将对象转化成字典的形式传。
form_obj = modelform.BookModelForm(instance=book_obj)
#locals()是将本地数据键值对的简写形式
return render(request, "edit_book.html", locals())
- book_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<title>查看书籍</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="alert alert-success text-center" role="alert">
<h1 class="text-center">图书管理系统</h1>
</div>
<div class="panel panel-default panel-primary">
<div class="panel-heading ">查看书籍</div>
<div class="panel-body">
<table class=" table table-striped">
<thead>
<tr>
<td>编号</td>
<td>书名</td>
<td>出版时间</td>
<td>价格</td>
<td>出版社</td>
<td>作者</td>
<td>操作</td>
</tr>
</thead>
{% for book in book_obj %}
<tbody>
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.title }}</td>
<td>{{ book.publishDate|date:"Y-m-d" }}</td>
<td>{{ book.price}}</td>
<td>{{ book.publishes.name }}</td>
<td>{{ book.author_name }}</td>
<td>
<a href="{% url 'edit' book.pk %}" class="btn btn-danger">编辑</a>
<a href="{% url 'delete' book.pk %}" class="btn btn-warning">删除</a>
</td>
</tr>
</tbody>
{% endfor %}
</table>
<a href="{% url 'add' %}" class="btn btn-success pull-right">添加书籍</a>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
- add_book.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
<title>Title</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
{% csrf_token %}
{% for field in new_book %}
<div class="form-group">
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<button type="submit" class="btn btn-success pull-right">保存</button>
</form>
</div>
</div>
</div>
</body>
</html>
- edit_book.html
{% extends "add_book.html" %}
9. 通过对Form组件和ModelForm的对比
- ModelForm增加了Form组件和对应数据库之间的联系,进而简化了Form类的代码
- ModelForm继承了Form组件中的所有方法的同时,简化了前端获取数据和对应数据库之间的数据对接,不需要在对数据的内容做过多的操作。
10. ModelForm进阶(同Form组件)
- 批量添加样式:
通过重写ModelForm类的init方法来实现。
# 通过修改类的初始化方法达到批量添加共同属性的目的
def __init__(self, *args, **kwargs):
super(BookModelForm, self).__init__(*args, **kwargs)
# for field_name {in self.base_fields:
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
'class': 'form-control'
})
原文地址:https://www.cnblogs.com/daviddd/p/12051115.html
- SQLiScanner:又一款基于SQLMAP和Charles的被动SQL 注入漏洞扫描工具
- 逆向工厂(一):从hello world开始
- Android系统到底安不安全?细数Android7.0 Nougat的几大安全增强功能
- 冒用数字签名的对抗:亟需加强的签名审核
- Twitter开源云环境时间序列数据断层检测工具BreakoutDetection
- 用Python的长短期记忆神经网络进行时间序列预测
- 【问底】许鹏:使用Spark+Cassandra打造高性能数据分析平台(一)
- 隐秘通讯与跳板?C&C服务器究竟是怎么一回事
- 灵活布置、可二次开发的乌云公开漏洞及知识库搜索
- 干货 | 2014年我国大数据发展分析报告
- 这个恶意软件“奇葩”的反虚拟机技巧
- Android漏洞CVE-2015-3825分析及exploit实战:从Crash到劫持PC
- VaultPasswordView:可用于查看windows Vault密码的工具
- 逆向工厂(二):静态分析技术
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android实现两圆点之间来回移动加载进度
- Android使用第三方库实现日期选择器
- Android Activity向右滑动返回
- 大多数人都不懂的搜索引擎技巧,掌握这几点,提升你的工作效率
- 如何使用Flutter实现58同城中的加载动画详解
- Android Gradle开发指南详解
- Hexo+Github搭建个人博客:Hexo添加分类标签
- Android自定义酒店日期选择器
- Android实现apk插件方式换肤的实例讲解
- 基于Spark Graphx实现ID-Mapping
- Nginx keepalived一主一从高可用,手把手带你一步一步配置!
- Android实现自动轮询的RecycleView
- Android自定义钟表特效
- Android MediaPlayer 音频倍速播放 调整播放速度问题
- Android 简单实现倒计时功能