Form操作之错误信息操作

1. 用户发送请求过来

2. for 循环对字段进行正则表达式的验证  fields.clean(value)

3. 自定义clean_字段() 进行名字段值正确性的校验

4. 自定义clean()的内容校验,会进行异常信息的捕捉

5. post_clean()方法的校验,不允许抛出异常,self.add_error(进行校验)

注意  self.add_error(None, ValidatorError(‘’))   这里虽然写的是None,但实际上会转换为__all__

Django内部会进行转换的:self.add_error(‘__all__’, ValidatorError(‘’))

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('fm/', views.fm),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models,fields
class Fm(forms.Form):
username = fields.CharField(max_length=32, label='用户名')
email = fields.EmailField(label='邮箱') # 这里是对username字段的内容进行验证的
def _clean_username(self):
data = self.cleaned_data['username']
if (data == 'root'):
return data # 验证通过,返回一个结果给forms.py中full_clean()方法的调用处
else:
from django.core.exceptions import ValidationError
# 这里的异常也是forms.py中full_clean()的异常捕获
raise ValidationError("请使用root用户登录...") # 这里实际上是调用 _clean_form(self)里的clean()进行错误拓展
def clean(self):
data = self.cleaned_data['username']
email = self.cleaned_data['email']
if (data == 'root' and email == 'root@live.com'):
pass # 因为父级别的_post_clean也是什么都不操作
else:
from django.core.exceptions import ValidationError
# 这里的异常是forms._clean_form()的异常捕获
raise ValidationError("用户名或email错误...")
return self.cleaned_data # _post_clean和_clean_form里面的clean()效果同,所以这里隐去
# 这里是个_post_clean里面的Hook,里面的方法体为空
# def _post_clean(self):
# data = self.cleaned_data['username']
# email = self.cleaned_data['email']
# if (data == 'root' and email == 'root@live.com'):
# pass # 因为父级别的_post_clean也是什么都不操作
# else:
# from django.core.exceptions import ValidationError
# # 这里的异常是forms._clean_form()的异常捕获
# raise ValidationError("用户名或email错误...") def fm(request):
if request.method == "GET":
obj = Fm()
return render(request, 'fm.html', {"obj": obj})
else:
obj = Fm(request.POST)
obj.is_valid()
# data = obj.clean() 因为Fm()里面覆写了该方法,所以直接调用cleaned_data获取值即可
data = obj.cleaned_data
error = obj.errors
print('错误信息',error)
print('正确信息:',data)
return render(request, 'fm.html', {"obj": obj})

templates/fm.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
{# 模版语言一: 逐个输出内容#}
<h5>模版语言,逐个输出</h5>
{{ obj.username }}
{{ obj.email }}
<hr>
{# 模版语言二: 一次性输出全部内容,如果是as_p,则是在P标签内,as_ul是ul标签 #}
<h5>模版语言,一次性配合lable标签输出全部字段</h5>
{{ obj.as_p }}
{{ obj.as_ul }}
<table>{{ obj.as_table }}</table>
<hr>
<form action="/fm/" method="post">
{{ obj.as_p }}
<input type="submit" value="提交"/>
</form>
</body>
</html>

页面显示;

初始化数据库

python manage.py makemigrations
python manage.py migrate

Form操作之is_valid()源码解析

进入full_clean()方法

full_clean()方法:

_clean_fields()

add_error(name,e)

_clean_form():

_post_form()

Form操作之前台下拉框实时显示数据库内容

问题现象:无法获取数据库内最新的数据

解决一: 调用父类的构造方法,每次调用函数之前重新获取数据

class Fm(forms.Form):
username = fields.CharField(max_length=32, label='用户名')
email = fields.EmailField(label='邮箱')
user_type=fields.ChoiceField(choices=models.UT.objects.values_list('id', 'caption')) def __init__(self, *args, **kwargs):
super(Fm, self).__init__(*args, **kwargs)
self.fields['user_type'].widget.choices = models.UT.objects.all().values_list('id', 'caption')

最终显示内容:

附完整源码:

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('fm/', views.fm),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
class Fm(forms.Form):
username = fields.CharField(max_length=32, label='用户名')
email = fields.EmailField(label='邮箱')
user_type=fields.ChoiceField(choices=models.UT.objects.values_list('id', 'caption'))
# 方案一:
def __init__(self, *args, **kwargs):
super(Fm, self).__init__(*args, **kwargs)
self.fields['user_type'].widget.choices = models.UT.objects.all().values_list('id', 'caption')
# 方案二:
from django.forms import models as filed_models
# 这里的all()返回的是一个对象,前台页面显示的始终是object,但是看源码又有value值
# 同时这里的limit_choices_to并无明显效果显示,在ModelForm里面效果显著
user_type2 = filed_models.ModelChoiceField(queryset=models.UT.objects.all(),
to_field_name='caption',
limit_choices_to={'id':'(1,3)'},)
# 多选框
user_type3 = filed_models.ModelMultipleChoiceField(queryset=models.UT.objects.all(),
to_field_name='caption',
limit_choices_to={'id': '(1,3)'}, ) def fm(request):
if request.method == "GET":
obj = Fm()
return render(request, 'fm.html', {"obj": obj})

models.py

from django.db import models
class U(models.Model):
id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列
name = models.CharField(max_length=32)
email = models.CharField(max_length=32)
userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系] class UT(models.Model):
caption = models.CharField(max_length=32)
def __str__(self):
return self.caption

templates/fm.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
{# 模版语言一: 逐个输出内容#}
<h5>模版语言,逐个输出</h5>
{{ obj.username }}
{{ obj.email }}
<hr>
{# 模版语言二: 一次性输出全部内容,如果是as_p,则是在P标签内,as_ul是ul标签 #}
<h5>模版语言,一次性配合lable标签输出全部字段</h5>
{{ obj.as_p }}
{{ obj.as_ul }}
<table>{{ obj.as_table }}</table>
<hr>
<form action="/fm/" method="post">
{{ obj.as_p }}
<input type="submit" value="提交"/>
</form>
</body>
</html>

页面显示;

初始化数据库

python manage.py makemigrations
python manage.py migrate

Form操作更多参考 :http://www.cnblogs.com/wupeiqi/articles/6144178.html

Python学习---Form拾遗180322的更多相关文章

  1. Python学习---Model拾遗[1]180318

    Model: 强大的数据库操作,弱小的数据验证 Form:  强大的数据验证 ModelForm: 强大的数据验证 + 弱小的数据库操作 Model拾遗 Model基本操作 1. 创建数据库表2. 修 ...

  2. Python学习---Django拾遗180328

    Django之生命周期 前台发送URL请求到Django的中间件进行内容校验,完成校验后到达路由映射文件url.py,然后调用视图函数views.py里面的函数进行内容处理[ 1.操作数据库进行数据读 ...

  3. Python学习---ModelForm拾遗180325

    ModelForm适用于前台验证和后台直接操作数据库的前后台未做分离,可以一次执行验证和保存数据的场景. 注意:  1.  ModelForm里面没有删除方法,需要手动删除内容 2. ModelFor ...

  4. Python学习---Model拾遗[2]180318

    Model的字段及字段参数: Model字段: 数字        字符串(带正则的字段)        时间        文件       特殊字段:(一对一,一对多,多对多) Models.py ...

  5. Python 学习 第十篇 CMDB用户权限管理

    Python 学习 第十篇 CMDB用户权限管理 2016-10-10 16:29:17 标签: python 版权声明:原创作品,谢绝转载!否则将追究法律责任. 不管是什么系统,用户权限都是至关重要 ...

  6. Python:Python学习总结

    Python:Python学习总结 背景 PHP的$和->让人输入的手疼(PHP确实非常简洁和强大,适合WEB编程),Ruby的#.@.@@也好不到哪里(OO人员最该学习的一门语言). Pyth ...

  7. python学习博客地址集合。。。

    python学习博客地址集合...   老师讲课博客目录 http://www.bootcdn.cn/bootstrap/  bootstrap cdn在线地址 http://www.cnblogs. ...

  8. python学习笔记目录

    人生苦短,我学python学习笔记目录: week1 python入门week2 python基础week3 python进阶week4 python模块week5 python高阶week6 数据结 ...

  9. 【old】Python学习笔记

    上学期看视频记得,也没学到多少,目前打算一边通过<Python学习手册 第四版>提高核心语法(太厚了 噗),一边学习Python Web开发 然后这里的多任务编程和网络编程是暑假学的 5. ...

随机推荐

  1. Linux-文件和目录属性

    文件系统的是用来组织和排列文件存取的,所以它是可见的,在Linux中,我们可以通过ls等工具来查看其结构,在Linux系统中,见到的都是树形结构:比如操作系统安装在一个文件系统中,他表现为由/ 起始的 ...

  2. vue 分享知识点

    vue 分享模块清单 1.Vue 2.0之Vue实例和生命周期 2.vue 2.0之自定义指令 3.vue 2.0之观察者模式实现简单异步无限滚动 4.从JavaScript属性描述器剖析Vue.js ...

  3. VF

    VF 描述 Vasya is the beginning mathematician. He decided to make an important contribution to the scie ...

  4. [转]iCheck表单美化插件使用方法详解(含参数、事件等)

    本文转自:http://www.exp99.com/jswz/f2e/1408696007_34.html iCheck   特色: 1.在不同浏览器(包括ie6+)和设备上都有相同的表现 — 包括 ...

  5. CSS3完善和模式

    CSS3改善了传统盒模型架构,增强盒子构成要素的功能,扩展了盒模型显示的方式,具体描述如下 改善构造:除了传统的内容区域,边框区,补白区和边界区外,为盒子新增了轮廓区. 增强功能:内容增强CSS自动添 ...

  6. FineUI分组显示弹框最新的在最上边

    function TOBTCorrFun(obj){ var msgContent = JSON.parse(obj.dataJson); var tJson = JSON.stringify(obj ...

  7. 解决部分小程序无法获取UnionId的问题

    问题背景 通过观察数据,发现有一部分用户是无法获取到UnionId的 也就是接口返回的参数中不包含UnionId参数 看了微信文档的解释,只要小程序在开放平台绑定,就一定会分配UnionId 网上也有 ...

  8. mybatis之使用注解

    注解 使用对象 相对应的 XML 描述 @CacheNamespace 类 <cache> 为给定的命名空间(比如类)配置缓存.属性有:implemetation, eviction, f ...

  9. drupal7 hook_validate

    原文:function hook_validate function hook_validate($node, $form, &$form_state) { if (isset($node-& ...

  10. php 截取字符串指定长度

    ---恢复内容开始--- 一.直接取整,舍弃小数,保留整数:intval(): intval(9.21); /*结果是9*/ intval(9.89); /*结果是9*/ intval(string) ...