当前位置: 首页 > news >正文

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. 保存

相关文章:

  • CSS3渐变属性详解
  • 基于Springboot的在线考试系统
  • 内网安全实战防御技术和防御产品
  • CISSP 第9章:安全脆弱性、威胁和对策
  • 在 Mac 上轻松安装和配置 JMeter
  • CMake 中 install 命令用于定义安装规则,指定构建目标(如可执行文件、库等)和文件应该被安装到的位置。
  • 用可视化案例讲Rust编程1. 怎么能学会Rust
  • 从零开始:创建与维护一个成功的前端开源项目实操指南
  • 2024前端炫酷源码分享(附效果图及在线演示)
  • 揭开JavaScript数据类型的神秘面纱
  • 物理实验报告(二)| 表面张力
  • textarea 内容自适应,高度向上扩展
  • 元数据管理平台对比预研 Atlas VS Datahub VS Openmetadata
  • 2024年学习计划
  • LVGL,tabview用实体按键切换tab的事件回调实现
  • es的写入过程
  • Java小白进阶笔记(3)-初级面向对象
  • mockjs让前端开发独立于后端
  • MYSQL 的 IF 函数
  • rabbitmq延迟消息示例
  • 从输入URL到页面加载发生了什么
  • 复杂数据处理
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 关于Flux,Vuex,Redux的思考
  • 机器学习学习笔记一
  • 跨域
  • 如何优雅地使用 Sublime Text
  • 数据仓库的几种建模方法
  • 物联网链路协议
  • 在Mac OS X上安装 Ruby运行环境
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (2020)Java后端开发----(面试题和笔试题)
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (转)甲方乙方——赵民谈找工作
  • (转)母版页和相对路径
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .Net Core缓存组件(MemoryCache)源码解析
  • .net mvc部分视图
  • .NET MVC之AOP
  • .net 按比例显示图片的缩略图
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET程序员迈向卓越的必由之路
  • @Builder用法
  • @开发者,一文搞懂什么是 C# 计时器!