d:/python/demo3
目標(biāo)
- form表單
- get/post
- Request對(duì)象
- 利用HTML表單開(kāi)發(fā)注冊(cè)功能
- Django表單改造注冊(cè)功能
- 數(shù)據(jù)綁定與校驗(yàn)(了解)
- 數(shù)據(jù)驗(yàn)證錯(cuò)誤信息(了解)
- 實(shí)戰(zhàn)任務(wù)
表單
表單有如下特征:
- 1、通過(guò)各種<input>、<select>等標(biāo)簽進(jìn)行數(shù)據(jù)與參數(shù)的對(duì)應(yīng),用來(lái)作為數(shù)據(jù)載體,傳遞數(shù)據(jù)。
- 2、在<form>標(biāo)簽中的action屬性定義url請(qǐng)求的地址。
- 3、在<form>標(biāo)簽中的method屬性定義Http method。
get/post
get/post及區(qū)別略
Request對(duì)象
每個(gè)view函數(shù)的第一個(gè)參數(shù)是一個(gè)HttpRequest對(duì)象。
request對(duì)象的屬性
request.scheme
代表請(qǐng)求的方案,http或者h(yuǎn)ttps
request.path
請(qǐng)求的路徑,比如請(qǐng)求127.0.0.1/org/list,那這個(gè)值就是/org/list
request.method
表示請(qǐng)求使用的http方法,GET或者POST請(qǐng)求
request.encoding
表示提交數(shù)據(jù)的編碼方式
request.GET
獲取GET請(qǐng)求
request.POST
獲取post的請(qǐng)求,比如前端提交的用戶密碼,可以通過(guò)request.POST.get()來(lái)獲取
另外:如果使用 POST 上傳文件的話,文件信息將包含在 FILES 屬性中
request.COOKIES
包含所有的cookie
request.META
一個(gè)標(biāo)準(zhǔn)的Python 字典,包含所有的HTTP 首部。具體的頭部信息取決于客戶端和服務(wù)器,下面是一些示例:
CONTENT_LENGTH —— 請(qǐng)求的正文的長(zhǎng)度(是一個(gè)字符串)。
CONTENT_TYPE —— 請(qǐng)求的正文的MIME 類型。
HTTP_ACCEPT —— 響應(yīng)可接收的Content-Type。
HTTP_ACCEPT_ENCODING —— 響應(yīng)可接收的編碼。
HTTP_ACCEPT_LANGUAGE —— 響應(yīng)可接收的語(yǔ)言。
HTTP_HOST —— 客服端發(fā)送的HTTP Host 頭部。
HTTP_REFERER —— Referring 頁(yè)面。
HTTP_USER_AGENT —— 客戶端的user-agent 字符串。
QUERY_STRING —— 單個(gè)字符串形式的查詢字符串(未解析過(guò)的形式)。
REMOTE_ADDR —— 客戶端的IP 地址。
REMOTE_HOST —— 客戶端的主機(jī)名。
REMOTE_USER —— 服務(wù)器認(rèn)證后的用戶。
REQUEST_METHOD —— 一個(gè)字符串,例如"GET" 或"POST"。
SERVER_NAME —— 服務(wù)器的主機(jī)名。
SERVER_PORT —— 服務(wù)器的端口(是一個(gè)字符串)
request.user
一個(gè) AUTH_USER_MODEL 類型的對(duì)象,表示當(dāng)前登錄的用戶。
如果用戶當(dāng)前沒(méi)有登錄,user 將設(shè)置為 django.contrib.auth.models.AnonymousUser 的一個(gè)實(shí)例。你可以通過(guò) is_authenticated() 區(qū)分它們
把request傳給前端的時(shí)候,前端可以通過(guò) {% if request.user.is_authenticated %}判斷用戶時(shí)候登錄
request.session
一個(gè)既可讀又可寫的類似于字典的對(duì)象,表示當(dāng)前的會(huì)話
利用form表單開(kāi)發(fā)注冊(cè)功能
接下來(lái)我們使用HTML表單,模擬一個(gè)用戶注冊(cè)功能,并演示如何使用HTML表單以及request對(duì)象:
- 用戶的信息包括:用戶名、密碼、昵稱、郵件地址、自我介紹。
- 訪問(wèn)/register注冊(cè)頁(yè)面,填寫用戶信息,點(diǎn)擊[注冊(cè)]按鈕使用post方式提交表單。
- 提交后,后端校驗(yàn)數(shù)據(jù)有效性,用戶名/密碼/昵稱為必填項(xiàng),郵件地址中必須包含'@'。如果不滿足有效性,則給出提示。
- 通過(guò)有效性驗(yàn)證后,頁(yè)面跳轉(zhuǎn)到新的歡迎頁(yè),并回顯用戶數(shù)據(jù)。
1)d:/python/demo3下新建Django工程
(略)
2)命令行輸入以下命令,新建一個(gè)formapp,此應(yīng)用用于測(cè)試form
python manage.py startapp formapp
3)setting.xml里注冊(cè)formapp
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'formapp',
]
4)主urls加入以下語(yǔ)句
path('forms',include("formapp.urls")),
5)formapp下新建urls.py 交輸入以下內(nèi)容
from django.urls import path
from . import views
urlpatterns = [
path('', views.goregister, name='goregister'),
path('register', views.register),
]
6)views.py
def register(request):
errors = []
user = {}
if request.method == 'POST':
if not request.POST.get('nickname', ''):
errors.append('請(qǐng)輸入昵稱.')
if not request.POST.get('username', ''):
errors.append('請(qǐng)輸入用戶名.')
if not request.POST.get('password', ''):
errors.append('請(qǐng)輸入密碼.')
if request.POST.get('email') and '@' not in request.POST['email']:
errors.append('請(qǐng)輸入有效的郵件地址.')
if not errors:
user = {
'nickname': request.POST['nickname'],
'username': request.POST['username'],
'password': request.POST['password'],
'email': request.POST.get('email', ''),
'self_intro': request.POST.get('self_intro', ''),
}
save_user(user)
# 使用post提交的表單,Django要求必須使用csrf標(biāo)簽,渲染模板時(shí),請(qǐng)使用render方法
return render(request, 'success.html', user)
return render(request, 'register.html', {
'errors': errors,
'nickname': request.POST.get('nickname', ''),
'username': request.POST.get('username', ''),
'password': request.POST.get('password', ''),
'email': request.POST.get('email', ''),
'self_intro': request.POST.get('self_intro', ''),
})
def save_user(user):
# 省略保存用戶實(shí)現(xiàn)過(guò)程
pass
7)頁(yè)面
formapp/templates目錄下新建register.html success.html
register.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Neuedu Django ch03</title>
</head>
<body>
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<!-- action屬性不填寫時(shí),等同于將表單提交到當(dāng)前頁(yè)面的請(qǐng)求地址 -->
<form action="/forms/register" method="post">
{# csrf標(biāo)簽是Django提供的防止偽裝提交請(qǐng)求的功能。POST方法提交的表格,必須有此標(biāo)簽。 #}
{% csrf_token %}
<p>昵稱: <input type="text" name="nickname" value="{{ nickname }}" ></p>
<p>用戶名: <input type="text" name="username" value="{{ username }}" ></p>
<p>密碼: <input type="text" name="password" value="{{ password }}" ></p>
<p>郵件地址: <input type="text" name="email" value="{{ email }}" ></p>
<p>自我介紹: <textarea name="self_intro" rows="10" cols="50">{{ self_intro }}</textarea></p>
<input type="submit" value="注冊(cè)">
</form>
</body>
</html>
success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Neuedu Django ch03</title>
</head>
<body>
<h1>恭喜注冊(cè)成功!您的用戶信息如下:</h1>
<p>昵 稱: {{ nickname }}</p>
<p>用 戶 名: {{ username }}</p>
<p>郵件地址: {{ email }}</p>
<p>自我介紹: {{ self_intro }}</p>
</body>
</html>
8)運(yùn)行效果


Django表單改造注冊(cè)功能(中英文兩套)
d:/python/demo3
上述功能,如果頁(yè)面需要提交的字段比較多,后臺(tái)views會(huì)特別麻煩。用Django表單組件可以簡(jiǎn)化這部分工作
Django帶有一個(gè)form庫(kù),稱為django.forms,這個(gè)庫(kù)可以處理包括HTML表單顯示以及驗(yàn)證的很多內(nèi)容。接下來(lái)我們來(lái)深入了解一下form庫(kù),學(xué)習(xí)如何使用Django表單,最后試著使用它來(lái)重寫我們的用戶注冊(cè)功能。
1)我們?cè)趕ettings目錄創(chuàng)建一個(gè)python文件,form.py,繼承自django.forms.Form,在RegisterForm中定義一些屬性,與模型寫法類似
from django import forms
class RegisterForm(forms.Form):
nickname = forms.CharField(max_length=20)
username = forms.CharField()
password = forms.CharField()
email = forms.EmailField(required=False)
self_intro = forms.CharField(required=False, widget=forms.Textarea)
class RegisterFormChinese(forms.Form):
nickname = forms.CharField(max_length=20, label='昵稱')
username = forms.CharField(label='用戶名')
password = forms.CharField(label='密碼')
email = forms.EmailField(required=False, label='郵件地址')
self_intro = forms.CharField(required=False, widget=forms.Textarea, label='自我介紹')
2)改造views.py關(guān)鍵代碼
from demo3.form import RegisterForm, RegisterFormChinese
def register(request):
# get請(qǐng)求訪問(wèn)頁(yè)面時(shí),返回空表單,post請(qǐng)求提交數(shù)據(jù)時(shí)進(jìn)行表單驗(yàn)證和頁(yè)面跳轉(zhuǎn)
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
return render(request, 'success.html', {'form': form})
else:
form = RegisterForm()
return render(request, 'register.html', {'form': form})
def register_chinese(request):
if request.method == 'POST':
form = RegisterFormChinese(request.POST)
if form.is_valid():
# 將用戶提交的表單回顯,并設(shè)置不可編輯
# form.fields 返回一個(gè)OrderedDict
# 我們遍歷這個(gè)存儲(chǔ)著表單字段的字典,并通過(guò)widget.attrs設(shè)定他們的html屬性
for f in form.fields.values():
f.widget.attrs['disabled'] = 'disabled'
return render(request, 'success.html', {'form': form})
else:
form = RegisterFormChinese()
return render(request, 'register_chinese.html', {'form': form})
3)改造register.html
<form action="/forms/register/" method="post">
{% csrf_token %}
<table>{{ form }}</table>
<input type="submit" value="Submit" />
</form>
4)register_chinese.html
<form action="/forms/register_chinese/" method="post">
{% csrf_token %}
<table>{{ form }}</table>
<input type="submit" value="提交" />
</form>
4)改造success.html
<body>
<h1>注冊(cè)成功</h1>
<table>{{ form }}</table>
</body>
5)formapp.urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.goregister, name='goregister'),
path('register/', views.register),
path('register_chinese/', views.register_chinese),
]
6)啟動(dòng)服務(wù)
python manage.py runserver
7)瀏覽器輸入地址測(cè)試
http://127.0.0.1:8000/forms/register/
http://127.0.0.1:8000/forms/register_chinese/
數(shù)據(jù)綁定與校驗(yàn)證(了解)
form.is_bound()屬性查看表單對(duì)象是否已經(jīng)綁定
form.is_valid()是否所有字段驗(yàn)證通過(guò),返回True/False
數(shù)據(jù)驗(yàn)證錯(cuò)誤信息(了解)
f.errors()提供了一個(gè)字段與錯(cuò)誤消息相映射的字典表。
代碼解釋
我們將頁(yè)面展示與頁(yè)面提交的地址都設(shè)置為formapp/register
在視圖中通過(guò)request對(duì)象的method方法判斷頁(yè)面請(qǐng)求的get/post方法,進(jìn)行不同的操作。
當(dāng)頁(yè)面提交get請(qǐng)求時(shí)(直接訪問(wèn)url地址),初始化一個(gè)空的表單對(duì)象,并返回給頁(yè)面。
當(dāng)頁(yè)面提交post請(qǐng)求時(shí)(通過(guò)頁(yè)面html提交表單時(shí)),驗(yàn)證表單并跳轉(zhuǎn)到成功頁(yè)面。