django中只使用ModleForm的表单验证
作者:野生大虾 发布时间:2021-02-03 15:41:50
标签:django,ModleForm
主题
众所周知,django.forms
极其强大,不少的框架也借鉴了这个模式,如Scrapy
。在表单验证时,django.forms
是一绝,也是面向对象的经典表现。但要用它来渲染表单那就不好玩了,除非写框架。本文章主要缕一缕如何使用django.forms来做表单验证。
django项目基本信息
models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=50, verbose_name='标题')
content = models.TextField(verbose_name='内容')
create_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
forms.py
同目录下创建一个forms.py
from django.forms import ModelForm
from django import forms
from . models import Article
from django.core.exceptions import ValidationError
class ArticleForm(ModelForm):
class Meta:
model = Article
exclude = ['id']
def clean(self):
cleaned_data = super().clean()
title = cleaned_data.get('title')
if 'My' not in title:
raise ValidationError('标题中必须包含My字样', code='title')
views.py
在views中,创建一个增加Article的方法
def add(request):
if request.method == 'GET':
return render(request, 'add.html')
else:
form = ArticleForm(request.POST)
# 主要了解的是表单的验证
if form.is_valid():
form.save()
return HttpResponseRedirect('/show/')
else:
form.errors.as_data() # {'__all__': [ValidationError(['标题中必须包含My字样'])]}
form.errors.get_context() # {'errors': dict_items([('__all__', ['标题中必须包含My字样'])]), 'error_class': 'errorlist'}
d = form.errors.get_json_data() # {'__all__': [{'message': '标题中必须包含My字样', 'code': 'title'}]}
return HttpResponse(d.get('__all__'))
核心分析
如果是在admin中使用ModelForm的验证,那也是非常方便的,如果我们要在用户的前端响应中使用表单验证,且又不通过django.forms渲染的表单来传递验证结果,则需要看看源码:ModelForm.errors
。errors
是ErrorDict()
的实例,ErrorDict
源码:
class ErrorDict(dict, RenderableErrorMixin):
"""
A collection of errors that knows how to display itself in various formats.
The dictionary keys are the field names, and the values are the errors.
"""
template_name = "django/forms/errors/dict/default.html"
template_name_text = "django/forms/errors/dict/text.txt"
template_name_ul = "django/forms/errors/dict/ul.html"
def __init__(self, *args, renderer=None, **kwargs):
super().__init__(*args, **kwargs)
self.renderer = renderer or get_default_renderer()
def as_data(self):
return {f: e.as_data() for f, e in self.items()}
def get_json_data(self, escape_html=False):
return {f: e.get_json_data(escape_html) for f, e in self.items()}
def get_context(self):
return {
"errors": self.items(),
"error_class": "errorlist",
}
三个方法返回的都是字典,但数据结构不同,可以看情况而定。值得注意的是,在ArticleForm
中,raise ValidationError时,如果code传入参数时,它将会在get_context()
中显式体现出来。
总结
1、掌握这个原理,传统的全栈开发可以节省更多的时间。
2、多看源码
来源:https://www.cnblogs.com/mooremok/p/17003453.html


猜你喜欢
- 目前,计算机上主流的操作系统有Windows、Unix、Mac OS等,os模块为多操作系统的访问提供了相关功能的支持,涉及对文件相关操作功
- 最近媳妇工作上遇到一个重复性劳动,excel表格查重,重复的标记起来,问我能不能写个程序让它自动查重标记必须安排第一次正儿八经写python
- 1、 变量及其作用域:变量分为“全局变量”和“局部变量”,“全局变量”申明在函数外部,可供所有函数使用,而“局部变量”申明在函数体内部,只能
- php面试题的题目: $a = '/a/b/c/d/e.php'; $b = '/a/b/12/34/c.php
- 前言:在Vue项目中,当访问的页面路由不存在或错误时,页面显示为一片空白。然而,通常我们需要对访问url不存在或者错误的情况下添加默认的40
- 机房一台服务器上的mysql运行一段时间了,突然出现了一个很奇怪的现象:重启后无法恢复了!准确情况是:启动mysql后随即就又关闭了。查看m
- 过滤html代码的函数,当然也可以使用正则表达式。<%Function FilterHTML(strToFilter)&nb
- 在运维过程中,经常需要读取mysql的结果输出并进行响应的处理,这节介绍如何用Python读取mysql结果表并进行相应的整理。进行mysq
- 1. 用Python每天给女神发送舔狗问候用Python自动发送最基本的邮件(主题+收件人)知识点邮件结构以263企业邮为例邮件形式内容最基
- 学习总结(1)和上一讲的模型训练是类似的,只是在线性模型的基础上加个sigmoid,然后loss函数改为交叉熵BCE函数(当然也可以用其他函
- mysql支持很多字段类型,包括数值类型、日期/时间类型和字符串(字符)类型;在使用时需要考虑到存储空间,存储效率;几种列类型描述使用了下述
- 建议先看vue瀑布流组件上拉加载更多再来食用本文,如果直接想看源码文末就是~文末新增组件优化,之所以没有删优化前的代码是想让以后自己还能看到
- 在html中引入外部js文件,并调用js文件中的带参函数1 项目结构2 编写a.js、test.html//a.jsfunction abc
- Filed under 数据库技术Leave a commentSQL Server命令行导数据两种方式bcp和sqlcmd先说一下bcp:
- 最近工作中写了几个存储过程,需要向存储过程中传递字符串,因为SQL Server 2000中没有内置类似于 split 的函数,只好自己处理
- 目前可以实现简单的计算。计算前请重置,设计的时候默认数字是0,学了半天就做出来个这么个结果,bug不少。 python3.5 + PyQt5
- 本文实例为大家分享了JS实现图片放大镜效果的具体代码,供大家参考,具体内容如下<!DOCTYPE html><html&g
- 介绍我编写了一个快速且带有斑点的python脚本,以可视化nmap和masscan的结果。它通过解析来自扫描的XML日志并生成所扫描IP范围
- 虚拟环境的搭建为什么要使用虚拟环境#1、使不同应用开发环境相互独立2、环境升级不影响其他应用,也不会影响全局的python环境3、防止出现包
- 今天我们说一下Redis中最后一个数据类型 “有序集合类型”,回首之前学过的几个数据结构,不知道你会不会由衷感叹,开源的世界真好,写这些代码