Python学习---Form拾遗180322
2023-09-11 14:20:11 时间
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
相关文章
- VS2013中Python学习笔记[Django Web的第一个网页]
- 【python基础】Linux环境下非root用户安装Python和第三方包
- Python学习笔记之常用函数及说明
- Python语言学习:Python语言学习之列表/元祖/字典/集合的简介、案例应用之详细攻略
- Python语言学习之打印输出那些事:python输出图表和各种吊炸天的字符串或图画、版权声明(如README.md)等之详细攻略
- Python编程语言学习:python中浅复制/深复制(或浅拷贝/深拷贝)的简介、案例应用注意事项之详细攻略
- Python语言编程学习:利用python输出当前python版本、MSC版本型号
- Python语言学习:python语言代码调试—异常处理之详细攻略
- Python语言学习之打印输出那些事:python输出图表和各种吊炸天的字符串或图画、版权声明(如README.md)等之详细攻略
- Python语言学习:创建/删除文件/文件夹、获取当前文件/文件夹路径(系统环境路径/目录)、获取当前文件夹下的所有子文件路径等代码(os系列用法)实现之详细攻略
- Python语言学习:利用python语言实现调用内部命令(python调用Shell脚本)—命令提示符cmd的几种方法
- Python语言学习之数值、小数、空格那些事:python和数值、小数、空格的使用方法之详细攻略
- 已解决2. Set PROTOCOL_BUPFERS_PYTHON_iMPLEMENTATION=python (but this will use pure-Python parsing and w
- 某宝付费买的价值上万的60G的Python学习资源,0基础轻松赚钱到手软,请低调使用,禁止外传
- 解惑Python模块学习,该如何着手操作...
- 值得学习练手的 5 个 Python 迷你程序(附代码)
- python自动化测试学习-Python测试框架之unittest和pytest
- Python21天学习挑战---day15 Python科学计算三剑客简介
- python学习之基本语法---语法规则---函数的基本用法(三)day9
- Python编程语言学习:python中浅复制/深复制(或浅拷贝/深拷贝)的简介、案例应用注意事项之详细攻略