Django 10 表单

表单的使用流程

1. 定义

1. terminal 输入 django-admin startapp the_14回车

2. tutorial子文件夹 settings.py  INSTALLED_APPS 中括号添加  "the_14",

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',"the_3","the_5","the_6","the_7","the_8","the_9","the_10","the_12","the_13","the_14",
]

3. tutorial子文件夹 urls.py 

from django.contrib import admin
from django.urls import path,include
import the_3.urlsurlpatterns = [path('admin/', admin.site.urls),path('the_3/', include('the_3.urls')),path('the_4/', include('the_4.urls')),path('the_5/', include('the_5.urls')),path('the_7/', include('the_7.urls')),path('the_10/', include('the_10.urls')),path('the_12/', include('the_12.urls')),path('the_13/', include('the_13.urls')),path('the_14/', include('the_14.urls')),
]

4. the_14 子文件夹添加 urls.py 

from django.urls import path
from .views import hellourlpatterns = [path('hello/', hello),
]

5. the_14\views.py 

from django.http import HttpResponse
from django.shortcuts import render# Create your views here.def hello(request):return HttpResponse('hello world')

6. 运行tutorial, 点击 http://127.0.0.1:8000/, 浏览器地址栏 127.0.0.1:8000/the_14/hello/  刷新 

7. 定义表单, 在 the_14文件夹创建 forms.py文件 

from django import formsclass NameForm(forms.Form):your_name = forms.CharField(label='你的名字', max_length=10)

8. the_14\views.py 

from django.http import HttpResponse
from django.shortcuts import render# Create your views here.def hello(request):return render(request, 'the_14/hello.html')

9. templates创建the_14子文件夹,再在 the_14子文件夹创建 hello.html 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>我是表单页面</h1>
</body>
</html>

10.  运行tutorial, 点击 http://127.0.0.1:8000/, 浏览器地址栏 127.0.0.1:8000/the_14/hello/  刷新 

11. 我想把form的内容渲染到前端去,首先the_14\views.py 写入

from django.http import HttpResponse
from django.shortcuts import render
from .forms import NameForm# Create your views here.def hello(request):form = NameForm()return render(request, 'the_14/hello.html', {'myform':form})

其次,在 template\the_14\hello.html 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>我是表单页面</h1>{{ myform }}
</body>
</html>

刷新网页

注意: 这里是没办法提交的,如果想提交, 需要嵌套一个form表单 

<body><h1>我是表单页面</h1><form action="">{{ myform }}</form>
</body>

表单的绑定与非绑定 

绑定就是说表单里面有值了,非绑定就是表单里面还没有值

表单提交了就是有值, 没有提交或者提交错误就是拿不到值, 拿不到值就是非绑定的状态。

怎么证明表单里面没有值

the_14\views.py 

from django.http import HttpResponse
from django.shortcuts import render
from .forms import NameForm# Create your views here.def hello(request):form = NameForm()import pdbpdb.set_trace()return render(request, 'the_14/hello.html', {'myform':form})

重新运行,刷新网页, terminal 输入 p form 回车

-> return render(request, 'the_14/hello.html', {'myform':form})
(Pdb) p form 
<NameForm bound=False, valid=Unknown, fields=(your_name)> 

bound=False 就是非绑定的状态 

terminal 再输入 p dir(form) 回车 

(Pdb) p dir(form)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__html__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_bound_fields_cache', '_clean_fields', '_clean_form', '_errors', '_html_output', '_post_clean', 'add_error', 'add_initial_prefix', 'add_prefix', 'as_p', 'as_table', 'as_ul', 'auto_id', 'base_fields', 'changed_data', 'clean', 'data', 'declared_fields', 'default_renderer', 'empty_permitted', 'error_class', 'errors', 'field_order', 'fields', 'files', 'full_clean', 'get_initial_for_field', 'has_changed', 'has_error', 'hidden_fields', 'initial', 'is_bound', 'is_multipart', 'is_valid', 'label_suffix', 'media', 'non_field_errors', 'order_fields', 'prefix', 'renderer', 'use_required_attribute', 'visible_fields']

is_bound 判断是否绑定的状态 

terminal 输入 p form.is_bound回车 , False指的是非绑定状态

(Pdb) p form.is_bound
False

terminal 输入 c回车, 结束调试

(Pdb) c
[07/Jan/2024 19:10:13] "GET /the_14/hello/ HTTP/1.1" 200 344

2.渲染

渲染表单到模板 

{{ form.as_table }}、{{ form.as_table }}、{{ form.as_p }}、{{ form.as_ul }}
{{ form.attr }}

the_14\hello.html 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>我是表单页面</h1><form action="" method="post">账号:{{ myform.your_name }}<input type="submit" value="上传"></form>
</body>
</html>

表单验证

  • 字段验证
  • 基于cleaned_data的类方法: clean_<fieldname>()
  • 基于cleaned_data的类方法:clean()

表单使用:其实是包含的两个请求的

第一个请求, get请求,这个请求可以拿到网页,展示页面

第二个请求, post请求,这个请求主要是提供数据给后台 , 注意:需要声明请求的url

templates\the_14\hello.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>我是表单页面</h1><form action="{% url 'form_hello' %}" method="post">账号:{{ myform.your_name }}<input type="submit" value="上传"></form>
</body>
</html>

the_14\urls.py

from django.urls import path
from .views import hellourlpatterns = [path('hello/', hello, name='form_hello'),
]

the_14\views.py 

from django.http import HttpResponse
from django.shortcuts import render
from .forms import NameForm# Create your views here.def hello(request):form = NameForm()# import pdb# pdb.set_trace()print(form.is_bound)return render(request, 'the_14/hello.html', {'myform':form})

刷新网页,输入名字panda, 点击上传,可以看到有两个False, 执行了两次。

False
[07/Jan/2024 20:56:07] "GET /the_14/hello/ HTTP/1.1" 200 352
False
[07/Jan/2024 20:56:13] "POST /the_14/hello/ HTTP/1.1" 200 352

第二次优化

the_14\views.py 

from Scripts.bottle import view
from django.http import HttpResponse
from django.shortcuts import render
from .forms import NameForm# Create your views here.# def hello(request):
#     request.method = 'GET'
#     form = NameForm()
#     # import pdb
#     # pdb.set_trace()
#     print(form.is_bound)
#     return render(request, 'the_14/hello.html', {'myform':form})class Hello(view):def get(self, request):form = NameForm()return render(request, 'the_14/hello.html', {'myform': form})def post(self,request):form = NameForm(request.POST)return render(request, 'the_14/hello.html', {'myform': form,'post':True})

the_14\urls.py

from django.urls import path
from .views import Hellourlpatterns = [# path('hello/', hello, name='form_hello'),path('hello/', Hello.as_view(), name='form_hello'),
]

刷新网页,输入 panda提交, 浏览器页面会出来 这里是post返回的内容。

字段验证

输入的字段受 max_length的长度限制

基于cleaned_data的类方法: clean_<fieldname>()

def post(self,request): form = NameForm(request.POST) # form.data # 属于原始数据 if form.is_valid(): # 是否校验过 print(form.cleaned_data) # 校验之后的数据, 干净的数据 return render(request, 'the_14/hello.html', {'myform': form,'post':True})

the_14\forms.py 

from django import formsclass NameForm(forms.Form):your_name = forms.CharField(label='你的名字', max_length=10)def clean_your_name(self):  # 专门校验your_nameyour_name = self.cleaned_data['your_name']if your_name.startswith('fuck'):raise forms.ValidationError('不能带脏字哟!')  # 不通过就主动抛出错误return your_name

the_14\views.py 

from Scripts.bottle import view
from django.http import HttpResponse
from django.shortcuts import render
from .forms import NameForm# Create your views here.# def hello(request):
#     request.method = 'GET'
#     form = NameForm()
#     # import pdb
#     # pdb.set_trace()
#     print(form.is_bound)
#     return render(request, 'the_14/hello.html', {'myform':form})class Hello(view):def get(self, request):form = NameForm()return render(request, 'the_14/hello.html', {'myform': form})def post(self,request):form = NameForm(request.POST)# form.data # 属于原始数据if form.is_valid(): # 是否校验过print(form.cleaned_data) # 校验之后的数据, 干净的数据else:print(form.errors)return render(request, 'the_14/hello.html', {'myform': form,'post':True})

刷新浏览器, 输入 fuck_panda, 上传就会出现以下内容

基于cleaned_data的类方法:clean()

如果有多个字段,应该怎么校验

the_14 \forms.py 添加 your_title = forms.CharField(label='你的头衔', max_length=10)

from django import formsclass NameForm(forms.Form):your_name = forms.CharField(label='你的名字', max_length=10)your_title = forms.CharField(label='你的头衔', max_length=10)def clean_your_name(self):  # 专门校验your_nameyour_name = self.cleaned_data['your_name']if your_name.startswith('fuck'):raise forms.ValidationError('不能带脏字哟!')  # 不通过就主动抛出错误return your_name

templates\the_14\hello.html
 

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>我是表单页面</h1><form action="{% url 'form_hello' %}" method="post">账号:{{ myform.your_name }} <br>头衔:{{ myform.your_title }} <br><input type="submit" value="上传"></form>{% if post %}<div>这里是post返回的内容</div>{% endif %}
</body>
</html>

刷新网页 

templates\the_14\hello.html 也可以只写 {{ myform }}

    <form action="{% url 'form_hello' %}" method="post">
{#        账号:{{ myform.your_name }} <br>#}
{#        头衔:{{ myform.your_title }} <br>#}{{ myform }}<input type="submit" value="上传"></form>

刷新网页 

the_14\forms.py 

from django import formsclass NameForm(forms.Form):your_name = forms.CharField(label='你的名字', max_length=10)your_title = forms.CharField(label='你的头衔', max_length=10)def clean_your_name(self):  # 专门校验your_nameyour_name = self.cleaned_data.get('your_name', '')if your_name.startswith('fuck'):raise forms.ValidationError('不能带脏字哟!')  # 不通过就主动抛出错误return your_name"""如果名字以pd开头,头衔必须使用金牌     """def clean(self):name = self.cleaned_data.get('your_name','')title = self.cleaned_data.get('your_title', '')if name.startswith('pd_') and title != "金牌":raise forms.ValidationError('如果名字以pd开头,头衔必须使用金牌')

刷新网页,输入 fuck_panda , pfshjln 上传 

如果使用['your_name']自定义的验证之后,还会进行clean()的联合校验,但是自定义没有通过,数据是不会填充到clean里面来的,所以
self.cleaned_data['your_name'] 是取不到值的
属性验证

the_14\forms.py

from django import forms
from django.core.validators import MinLengthValidatorclass NameForm(forms.Form):your_name = forms.CharField(label='你的名字', max_length=10,validators=[MinLengthValidator(3,'你的长度应该要大于3个')])your_title = forms.CharField(label='你的头衔', max_length=10)

刷新网页,填入 1, unknown, 点击上传, 浏览器返回 

自定义验证器 - (from django.core import validators)

the_14\forms.py 

from django import forms
from django.core.validators import MinLengthValidatordef my_validator(value):if len(value) < 4:raise forms.ValidationError('你写少了,赶紧修改')class NameForm(forms.Form):# your_name = forms.CharField(label='你的名字', max_length=10,validators=[MinLengthValidator(3,'你的长度应该要大于3个')])your_name = forms.CharField(label='你的名字', max_length=10, validators=[my_validator])your_title = forms.CharField(label='你的头衔', max_length=10)

刷新网页,输入 111, unknown 点击上传 

3. 提交

4. 校验

5. 保存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/604795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eslint+Prettier

1.Eslint js验证的规则标准,Vue也有自己的独特的验证规则,vue-eslint-plugin属于vue自己的验证规则。 如果不想报错,可以在package.json/rules里面进行关闭,默认是开启的,默认缩进是两个空格。 2.Prettier - Code formatter 使写代码更加的美观 可选的配置项: 例如: module…

STM32---中断

中断框图 一.中断 中断&#xff1a;当有中断请求时&#xff0c;CPU会停止处理当前的任务&#xff0c;转而去处理中断任务。 中断输入线有19/20根&#xff08;互联型号20根&#xff09;。 分类&#xff1a;系统异常&#xff08;10个&#xff09;和外部中断&#xff08;60个&…

20240107让Firefly的AIO-3399J开发板的Android11下配置为默认1080p录像

20240107让Firefly的AIO-3399J开发板的Android11下配置为默认1080p录像 2024/1/7 23:01 开发板&#xff1a;Firefly的AIO-3399J【RK3399】 SDK&#xff1a;rk3399-android-11-r20211216.tar.xz【Android11】 Android11.0.tar.bz2.aa【ToyBrick】 Android11.0.tar.bz2.ab Androi…

芯片验证入门踩坑指南(1)

因为一些原因&#xff0c;从华为数通C软件开发到海思这边做芯片验证&#xff0c;快一个月&#xff0c;说下一些心得与体会&#xff1a; 如何快速上手&#xff1a; 因为项目非常赶&#xff0c;几乎没有脱产学习时间&#xff0c;就是直接干项目&#xff0c;一开始不需要知道原理…

OpenCV-18图像的翻转和旋转

一、图像的翻转 使用API---cv.flip&#xff08;src, flipCode&#xff09; flipCode 0表示上下翻转 flipCode > 0表示左右翻转 flipCode < 0上下 左右翻转 或者使用np的翻转src[: : -1,: : -1]实现上下翻转。 示例代码如下&#xff1a; import cv2 import numpy…

项目管理工具Maven

Maven Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. Maven基础内容 2. Maven的依赖管…

数据版本控制利器LakeFS的介绍,以及其使用方法,与其它工具结合案例

LakeFS介绍 LakeFS 是一个开源的数据湖版本控制系统&#xff0c;可以帮助用户管理和控制数据湖中的数据版本。以下是LakeFS的一些主要用处和功能介绍&#xff1a; 数据版本控制&#xff1a;LakeFS 提供了类似于 Git 的版本控制功能&#xff0c;可以跟踪和管理数据湖中的数据版…

【一】使用vue-cli创建vue3的helloworld项目

不再推荐使用vue-cli命令创建vue3的项目&#xff0c;vue-cli 是 Vue 早期推出的一款脚手架&#xff0c;使用 webpack 创建 Vue 项目。后期推荐使用 create-vue&#xff0c;create-vue 是 Vue3 的专用脚手架&#xff0c;使用 vite 创建 Vue3 的项目(关注【二】使用create-vue创建…

超维空间M1无人机使用说明书——41、ROS无人机使用yolo进行物体识别

引言&#xff1a;用于M1无人机使用的18.04系统&#xff0c;采用的opencv3.4.5版本&#xff0c;因此M1无人机只提供了基于yolov3和yolov4版本的darknet_ros功能包进行物体识别&#xff0c;识别效果足够满足日常的物体识别使用&#xff0c;如果需要更高版本的yolov7或者yolov8&am…

十八:爬虫-JS逆向(下)

一&#xff1a;AES与DES DES对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥&#xff0c;信息的发送者。和信息的接收者在进行信息的传输与处理时&#xff0c;必须共同持有该密钥(称为对称密码),是一种对称加密算法。一般来说加密用的是encrypt()函…

thinkadmin安装步骤

一,先cmd运行安装命令 ### 创建项目( 需要在英文目录下面执行 ) composer create-project zoujingli/thinkadmin二,在confing中的database.php配置数据库 三,将仓库的data复制到app目录下 https://gitee.com/zoujingli/think-plugs-data 四,在cmd运行命令安装数据库 //…

第二百五十二回

文章目录 概念介绍实现方法示例代码 我们在上一章回中介绍了如何在页面中添加图片相关的内容&#xff0c;本章回中将介绍如何给组件添加阴影.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在本章回中介绍的阴影类似影子&#xff0c;只是它不像影子那么明显&a…

C++/OpenGL应用程序

图像应用程序大部分是 C 编写&#xff0c;OpenGL 调用实现与 3D 渲染相关任务将会使用一些扩展库: GLEW、GLM、GLFW、SOLL2 等。 GLFW 库包含 GLFWwindow 类&#xff0c;我们可以在其上进行 3D 场景绘制。OpenGL 也向我们提供了用于 GLSL 程序载入可编程着色阶段并对其进行编译…

【微服务】springcloud集成skywalking实现全链路追踪

目录 一、前言 二、环境准备 2.1 软件环境 2.2 微服务模块 2.3 环境搭建 2.3.1 下载安装包 2.3.2 解压并启动服务 2.3.3 访问web界面 三、搭建springcloud微服务 3.1 顶层公共依赖 3.2 用户服务模块 3.2.1 准备测试使用数据库 3.2.2 添加依赖 3.2.3 添加配置文件 …

how2heap-2.23-11-poison_null_byte

什么是poison_null_byte 当然不止这一种&#xff0c;下面最简单的形式 #include <malloc.h> int main() {char * a malloc(0x200);char * b malloc(0x200);size_t real_size malloc_usable_size(a);a[real_size] 0;return 0; }影响&#xff1a; chunk a&#xff0…

OpenVINS学习6——VioManagerHelper.cpp,VioManagerOptions.h学习与注释

前言 VioManager类里还有VioManagerHelper.cpp,VioManagerOptions.h这两个文件&#xff0c;也包含了一些函数&#xff0c;这次接着看这个 。 整体分析 void VioManager::initialize_with_gt(Eigen::Matrix<double, 17, 1> imustate) 给一个状态&#xff0c;然后初始化…

【C语言】段错误、内存溢出、内存泄漏(区别)、堆溢出、栈溢出

目录 段错误内存溢出内存泄漏栈溢出堆溢出栈溢出和堆溢出区别 段错误 什么时候会发生段错误&#xff1f; 段错误通常发生在访问非法内存地址的时候&#xff0c;即使用了野指针&#xff08;指向一个已删除的对象或者未申请访问受限内存区域的指针&#xff09;或这试图修改字符串…

【Matplotlib】基础设置之图像处理05

图像基础 导入相应的包&#xff1a; import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np %matplotlib inline导入图像 我们首先导入上面的图像&#xff0c;注意 matplotlib 默认只支持 PNG 格式的图像&#xff0c;我们可以使用 mpimg.im…

MySQL深入——9

如何正确的显示随机信息&#xff1f; 我们来模拟在英语单词app当中随机出现三个英语单词的情况&#xff0c;我们首先创建一张表words&#xff0c;然后给这个表当中插入10000条信息进行量化。 select word from words order by rand() limit 3&#xff1b; order by rand&…

基础数据结构第七期 Trie树

前言 Trie树大家能够掌握即可&#xff0c;其实用到的地方并不多&#xff0c;本文将为大家介绍一下。 一、Trie树的基本内容 1、根节点不包含字符&#xff0c;除根结点之外每一个结点都只包含一个字符&#xff1b; 2、字典树用边表示字母表示 3、从根节点到某一结点&#xff…