Django 10 表单

表单的使用流程

1. 定义

  1. terminal 输入 django-admin startapp the_14回车
  1. 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",
]
  1. tutorial子文件夹 urls.py
python 复制代码
from django.contrib import admin
from django.urls import path,include
import the_3.urls

urlpatterns = [
    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')),
]
  1. the_14 子文件夹添加 urls.py
python 复制代码
from django.urls import path
from .views import hello

urlpatterns = [
    path('hello/', hello),
]
  1. the_14\views.py
python 复制代码
from django.http import HttpResponse
from django.shortcuts import render


# Create your views here.

def hello(request):
    return HttpResponse('hello world')
  1. 运行tutorial, 点击 http://127.0.0.1:8000/, 浏览器地址栏 127.0.0.1:8000/the_14/hello/ 刷新
  1. 定义表单, 在 the_14文件夹创建 forms.py文件
python 复制代码
from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='你的名字', max_length=10)
  1. the_14\views.py
python 复制代码
from django.http import HttpResponse
from django.shortcuts import render


# Create your views here.

def hello(request):
    return render(request, 'the_14/hello.html')
  1. templates创建the_14子文件夹,再在 the_14子文件夹创建 hello.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>我是表单页面</h1>
</body>
</html>
  1. 运行tutorial, 点击 http://127.0.0.1:8000/, 浏览器地址栏 127.0.0.1:8000/the_14/hello/ 刷新
  1. 我想把form的内容渲染到前端去,首先the_14\views.py 写入
python 复制代码
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

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

python 复制代码
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()
    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 ```html Title

我是表单页面

账号:{{ myform.your_name }}
``` #### 表单验证 * 字段验证 * 基于cleaned_data的类方法: clean_\() * 基于cleaned_data的类方法:clean() 表单使用:其实是包含的两个请求的 第一个请求, get请求,这个请求可以拿到网页,展示页面 第二个请求, post请求,这个请求主要是提供数据给后台 , 注意:需要声明请求的url templates\\the_14\\hello.html ```html Title

我是表单页面

账号:{{ myform.your_name }}
``` the_14\\urls.py ```python from django.urls import path from .views import hello urlpatterns = [ path('hello/', hello, name='form_hello'), ] ``` the_14\\views.py ```python 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, 执行了两次。 ![](https://file.jishuzhan.net/article/1745330860304896001/7f880828b4fe8035926c0a915ac2602d.webp) 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 ```python 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 ```python from django.urls import path from .views import Hello urlpatterns = [ # path('hello/', hello, name='form_hello'), path('hello/', Hello.as_view(), name='form_hello'), ] ``` 刷新网页,输入 panda提交, 浏览器页面会出来 这里是post返回的内容。 ##### 字段验证 输入的字段受 max_length的长度限制 ##### 基于cleaned_data的类方法: clean_\() > 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 ```python from django import forms class NameForm(forms.Form): your_name = forms.CharField(label='你的名字', max_length=10) def clean_your_name(self): # 专门校验your_name your_name = self.cleaned_data['your_name'] if your_name.startswith('fuck'): raise forms.ValidationError('不能带脏字哟!') # 不通过就主动抛出错误 return your_name ``` the_14\\views.py ```python 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, 上传就会出现以下内容 ![](https://file.jishuzhan.net/article/1745330860304896001/ce7db1b7183ec51b68c8026148a65c7d.webp) ##### 基于cleaned_data的类方法:clean() 如果有多个字段,应该怎么校验 the_14 \\forms.py 添加 your_title = forms.CharField(label='你的头衔', max_length=10) ```python from django import forms class 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_name your_name = self.cleaned_data['your_name'] if your_name.startswith('fuck'): raise forms.ValidationError('不能带脏字哟!') # 不通过就主动抛出错误 return your_name ``` templates\\the_14\\hello.html ```html Title

我是表单页面

账号:{{ myform.your_name }}
头衔:{{ myform.your_title }}
{% if post %}
这里是post返回的内容
{% endif %} ``` 刷新网页 ![](https://file.jishuzhan.net/article/1745330860304896001/413914b813752043aee4069135d87da0.webp) templates\\the_14\\hello.html 也可以只写 {{ myform }} > > ``` >
> {# 账号:{{ myform.your_name }}
#} > {# 头衔:{{ myform.your_title }}
#} > {{ myform }} > >
> ``` 刷新网页 ![](https://file.jishuzhan.net/article/1745330860304896001/89bd022ffa299034c5f68bcaa317e34b.webp) the_14\\forms.py ```python from django import forms class 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_name your_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 上传 ![](https://file.jishuzhan.net/article/1745330860304896001/63a2d3f446c8765664aa597193a46c94.webp) ``` 如果使用['your_name']自定义的验证之后,还会进行clean()的联合校验,但是自定义没有通过,数据是不会填充到clean里面来的,所以 self.cleaned_data['your_name'] 是取不到值的 ``` ##### 属性验证 the_14\\forms.py ```python from django import forms from django.core.validators import MinLengthValidator class 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, 点击上传, 浏览器返回 ![](https://file.jishuzhan.net/article/1745330860304896001/89a780aa18931a66afe58f469866facb.webp) ##### 自定义验证器 - (from django.core import validators) the_14\\forms.py ```python from django import forms from django.core.validators import MinLengthValidator def 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 点击上传 ![](https://file.jishuzhan.net/article/1745330860304896001/e052a67ca1310e33474fdf56c54e6793.webp) ### 3. 提交 ## 4. 校验 ### 5. 保存

相关推荐
fish_study_csdn1 小时前
pytest 技术总结
开发语言·python·pytest
柏油1 小时前
MySQL InnoDB 行锁
数据库·后端·mysql
咖啡调调。1 小时前
使用Django框架表单
后端·python·django
BO_S__1 小时前
python调用ffmpeg对截取视频片段,可批量处理
python·ffmpeg·音视频
白泽talk1 小时前
2个小时1w字| React & Golang 全栈微服务实战
前端·后端·微服务
摆烂工程师1 小时前
全网最详细的5分钟快速申请一个国际 “edu教育邮箱” 的保姆级教程!
前端·后端·程序员
一只叫煤球的猫2 小时前
你真的会用 return 吗?—— 11个值得借鉴的 return 写法
java·后端·代码规范
就叫飞六吧2 小时前
如何判断你的PyTorch是GPU版还是CPU版?
人工智能·pytorch·python
Asthenia04122 小时前
HTTP调用超时与重试问题分析
后端
颇有几分姿色2 小时前
Spring Boot 读取配置文件的几种方式
java·spring boot·后端