Borang Django


Borang HTML ialah cara klasik interaktiviti tapak web. Bab ini akan memperkenalkan cara menggunakan Django untuk memproses data borang yang dihantar oleh pengguna.


Permintaan HTTP

Protokol HTTP berfungsi dalam cara "request-reply". Apabila pelanggan menghantar permintaan, mereka boleh menambahkan data pada permintaan itu. Dengan menghuraikan permintaan, pelayan boleh mendapatkan data yang dihantar oleh klien dan menyediakan perkhidmatan khusus berdasarkan URL.

Kaedah GET

Kami mencipta fail search.py ​​​​dalam projek sebelumnya untuk menerima permintaan pengguna:

# -*- coding: utf-8 -*-

from django.http import HttpResponse
from django.shortcuts import render_to_response

# 表单
def search_form(request):
	return render_to_response('search_form.html')

# 接收请求数据
def search(request):  
	request.encoding='utf-8'
	if 'q' in request.GET:
		message = '你搜索的内容为: ' + request.GET['q'].encode('utf-8')
	else:
		message = '你提交了空表单'
	return HttpResponse(message)

Tambah search_form.html dalam Borang templat direktori templat:

<html>
<head>
	<meta charset="utf-8" /> 
    <title>Search - w3cschool.cc</title>
</head>
<body>
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
</body>
</html>

urls.py Peraturannya diubah suai seperti berikut:

from django.conf.urls import *
from HelloWorld.view import hello
from HelloWorld.testdb import testdb
from HelloWorld import search

urlpatterns = patterns("",
	('^hello/$', hello),
	('^testdb/$', testdb),
	(r'^search-form/$', search.search_form),
	(r'^search/$', search.search),
)

Alamat akses: http://192.168.45.3:8000/search-form/ dan carian, hasilnya adalah seperti berikut:

1044.jpg

1045.jpg

Kaedah POST

Kami menggunakan kaedah GET di atas. Paparan paparan dan pemprosesan permintaan dibahagikan kepada dua fungsi.

Kaedah POST lebih biasa digunakan semasa menyerahkan data. Kami menggunakan kaedah ini di bawah dan menggunakan URL dan fungsi pemprosesan untuk memaparkan paparan dan mengendalikan permintaan pada masa yang sama.

Kami mencipta post.html dalam tmplate:

<html>
<head>
	<meta charset="utf-8" /> 
    <title>Search - w3cschool.cc</title>
</head>
<body>
	<form action="/search-post/" method="post">
		{% csrf_token %}
		<input type="text" name="q">
		<input type="submit" value="Submit">
	</form>

	<p>{{ rlt }}</p>
</body>
</html>

Di penghujung templat, kami menambah tanda rlt untuk menempah tempat bagi hasil pemprosesan jadual.

Terdapat juga teg {% csrf_token %} di belakang borang. Nama penuh csrf ialah Pemalsuan Permintaan Tapak Silang. Ini adalah ciri yang disediakan oleh Django untuk menghalang permintaan penyerahan yang menyamar. Borang yang dihantar menggunakan kaedah POST mesti mempunyai teg ini.

Buat fail search2.py baharu dalam direktori HelloWorld dan gunakan fungsi search_post untuk memproses permintaan POST:

# -*- coding: utf-8 -*-

from django.shortcuts import render
from django.core.context_processors import csrf

# 接收POST请求数据
def search_post(request):
	ctx ={}
	ctx.update(csrf(request))
	if request.POST:
		ctx['rlt'] = request.POST['q']
	return render(request, "post.html", ctx)

urls.py Peraturan diubah suai kepada bentuk berikut:

from django.conf.urls import *
from HelloWorld.view import hello
from HelloWorld.testdb import testdb
from HelloWorld import search
from HelloWorld import search2

urlpatterns = patterns("",
	('^hello/$', hello),
	('^testdb/$', testdb),
	(r'^search-form/$', search.search_form),
	(r'^search/$', search.search),
	(r'^search-post/$', search2.search_post),
)

Akses http: //192.168.45.3:8000/search-post/ Keputusan yang dipaparkan adalah seperti berikut:

1046.jpg

Setelah melengkapkan contoh di atas, struktur direktori kami ialah:

HelloWorld
|-- HelloWorld
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- models.pyc
|   |-- search.py
|   |-- search.pyc
|   |-- search2.py
|   |-- search2.pyc
|   |-- settings.py
|   |-- settings.pyc
|   |-- testdb.py
|   |-- testdb.pyc
|   |-- urls.py
|   |-- urls.pyc
|   |-- view.py
|   |-- view.pyc
|   |-- wsgi.py
|   `-- wsgi.pyc
|-- TestModel
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- admin.py
|   |-- models.py
|   |-- models.pyc
|   |-- tests.py
|   `-- views.py
|-- manage.py
`-- templates
    |-- base.html
    |-- hello.html
    |-- post.html
    `-- search_form.html

3 directories, 29 files

Objek permintaan

Parameter pertama setiap fungsi paparan ialah objek HttpRequest, seperti fungsi hello() berikut:

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello world")

Objek HttpRequest mengandungi beberapa maklumat tentang semasa URL permintaan:

pengguna

Hartanah

Penerangan

laluan

Laluan penuh ke halaman yang diminta, tidak termasuk nama domain—contohnya, "/hello/".

kaedah

Perwakilan rentetan kaedah HTTP yang digunakan dalam permintaan. Dinyatakan dalam semua huruf besar. Contohnya:

if request.method == 'GET':
do_something()
elif request.method == 'POST':
do_something_else()

GET

Objek seperti kamus yang mengandungi semua parameter HTTP GET. Lihat dokumentasi QueryDict.

SIARAN

Objek seperti kamus yang mengandungi semua parameter HTTP POST. Lihat dokumentasi QueryDict.

Pelayan juga mungkin menerima permintaan POST kosong. Dalam erti kata lain, borang menyerahkan permintaan melalui kaedah HTTP POST, tetapi tiada data dalam borang. Oleh itu, anda tidak boleh menggunakan pernyataan if request.POST untuk menentukan sama ada hendak menggunakan kaedah HTTP POST sebaliknya, gunakan if request.method == "POST" (lihat atribut kaedah dalam jadual ini).

Nota: POST tidak termasuk maklumat muat naik fail. Lihat atribut FILES.

PERMINTAAN

Untuk kemudahan, atribut ini ialah koleksi atribut POST dan GET, tetapi ia mempunyai ciri khas . Cari atribut POST dahulu, kemudian atribut GET. Belajar daripada $_REQUEST PHP.

Sebagai contoh, jika GET = {"name": "john"} dan POST = {"age": '34'}, maka nilai REQUEST["name"] ialah "john", REQUEST [" Nilai umur"] ialah "34".

Sangat disyorkan untuk menggunakan GET dan POST, kerana kedua-dua atribut ini lebih jelas dan kod yang ditulis lebih mudah difahami.

COOKIES

Objek kamus Python standard yang mengandungi semua kuki. Kekunci dan nilai adalah kedua-dua rentetan. Lihat Bab 12 untuk penjelasan lebih terperinci tentang kuki.

FAIL

Objek seperti kamus yang mengandungi semua fail yang dimuat naik. Setiap Kunci dalam FILES ialah nilai atribut nama dalam teg <input type="file" name="" /> Setiap nilai dalam FILES juga merupakan objek kamus Python standard, yang mengandungi tiga Kekunci berikut:

  • nama fail: Muat naik nama fail, diwakili oleh rentetan Python

  • jenis kandungan: Jenis kandungan fail yang dimuat naik

  • kandungan: Kandungan asal fail yang dimuat naik

Nota: Hanya apabila kaedah permintaan adalah POST dan halaman permintaan <form> mempunyai enctype="multipart/form- data " atribut hanya menyimpan data untuk FILES. Jika tidak, FILES ialah kamus kosong.

META

Kamus yang mengandungi semua maklumat pengepala HTTP yang tersedia. Contohnya:

  • CONTENT_LENGTH

  • CONTENT_TYPE

  • QUERY_STRING: Rentetan pertanyaan mentah tidak dihuraikan>< 🎜

  • REMOTE_ADDR: Alamat IP Pelanggan

  • REMOTE_HOST: Nama hos pelanggan

  • SERVER_NAME: Nama Hos Pelayan

  • SERVER_PORT: Port server

Pengepala dalam META ini diawali dengan HTTP_ sebagai kunci, contohnya:

  • HTTP_ACCEPT_ENCODING

  • HTTP_ACCEPT_LANGUAGE

  • HTTP_HOST: Maklumat pengepala hos HTTP yang dihantar oleh klien

  • HTTP_REFERER: halaman rujukan

  • HTTP_USER_AGENT: rentetan ejen pengguna pelanggan

  • HTTP_X_BEnder: maklumat pengepala X-Bender

    <🎜 🎜>

ialah objek django.contrib.auth.models.User, yang mewakili log masuk semasa pengguna.
Jika pengguna mengakses tidak dilog masuk pada masa ini, pengguna akan dimulakan kepada contoh django.contrib.auth.models.AnonymousUser.

Anda boleh mengenal pasti sama ada pengguna log masuk melalui kaedah is_authenticated() pengguna:


if request.user.is_authenticated():
    # Do something for logged-in users.
else:
    # Do something for anonymous users.

Atribut ini hanya tersedia apabila AuthenticationMiddleware dalam Django diaktifkan

sesi

Satu-satunya atribut yang boleh dibaca dan boleh ditulis, mewakili objek kamus sesi semasa. Harta ini hanya tersedia apabila sokongan sesi dalam Django diaktifkan. Lihat Bab 12.

raw_post_data

Data HTTP POST mentah, tidak dihuraikan. Berguna untuk pemprosesan lanjutan.

Objek Request juga mempunyai beberapa kaedah berguna:

< ke >Kaedah
Penerangan
方法描述
__getitem__(key)返回GET/POST的键值,先取POST,后取GET。如果键不存在抛出 KeyError。
这是我们可以使用字典语法访问HttpRequest对象。
例如,request["foo"]等同于先request.POST["foo"] 然后 request.GET["foo"]的操作。
has_key()检查request.GET or request.POST中是否包含参数指定的Key。
get_full_path()返回包含查询字符串的请求路径。例如, "/music/bands/the_beatles/?print=true"
is_secure()如果请求是安全的,返回True,就是说,发出的是HTTPS请求。

__getitem__(kunci)

Kembalikan nilai kunci GET/POST, mula-mula dapatkan POST, kemudian dapatkan GET . Membuang KeyError jika kunci tidak wujud.

Di sinilah kita boleh mengakses objek HttpRequest menggunakan sintaks kamus.

Contohnya, request["foo"] bersamaan dengan request.POST["foo"] dan kemudian request.GET["foo"].

方法描述

__getitem__

和标准字典的处理有一点不同,就是,如果Key对应多个Value,__getitem__()返回最后一个value。

__setitem__

设置参数指定key的value列表(一个Python list)。注意:它只能在一个mutable QueryDict 对象上被调用(就是通过copy()产生的一个QueryDict对象的拷贝).

get()

如果key对应多个value,get()返回最后一个value。

update()

参数可以是QueryDict,也可以是标准字典。和标准字典的update方法不同,该方法添加字典 items,而不是替换它们:

>>> q = QueryDict('a=1')

>>> q = q.copy() # to make it mutable

>>> q.update({'a': '2'})

>>> q.getlist('a')

 ['1', '2']

>>> q['a'] # returns the last

['2']

items()

和标准字典的items()方法有一点不同,该方法使用单值逻辑的__getitem__():

>>> q = QueryDict('a=1&a=2&a=3')

>>> q.items()

[('a', '3')]

values()

和标准字典的values()方法有一点不同,该方法使用单值逻辑的__getitem__():

<🎜>has_key()<🎜><🎜>Semak sama ada request.GET atau request.POST mengandungi Kunci yang ditentukan oleh parameter. <🎜><🎜><🎜><🎜>get_full_path()<🎜><🎜>Mengembalikan laluan permintaan yang mengandungi rentetan pertanyaan. Contohnya, "/music/bands/the_beatles/?print=true"<🎜><🎜><🎜><🎜>is_secure()<🎜><🎜>Return True jika permintaan itu selamat, iaitu dikeluarkan It's permintaan HTTPS. <🎜><🎜><🎜><🎜><🎜>objek QueryDict <🎜><🎜>Dalam objek HttpRequest, atribut GET dan POST ialah contoh kelas django.http.QueryDict. <🎜><🎜>QueryDict ialah kelas tersuai seperti kamus yang digunakan untuk mengendalikan situasi di mana satu kunci sepadan dengan berbilang nilai. <🎜><🎜>QueryDict melaksanakan semua kaedah kamus standard. Juga termasuk beberapa kaedah unik: <🎜><🎜><🎜><🎜><🎜>__getitem__<🎜><🎜><🎜><🎜> berbeza sedikit daripada pemprosesan kamus standard, iaitu, jika Kunci sepadan kepada berbilang Nilai, __getitem__() mengembalikan nilai terakhir. <🎜><🎜><🎜><🎜><🎜><🎜>__setitem__<🎜><🎜><🎜><🎜>Tetapkan senarai nilai kunci yang ditentukan oleh parameter (senarai Python). Nota: Ia hanya boleh dipanggil pada objek QueryDict boleh ubah (iaitu, salinan objek QueryDict yang dijana oleh copy()).<🎜><🎜><🎜><🎜><🎜><🎜>get() < 🎜><🎜><🎜><🎜>Jika kunci sepadan dengan berbilang nilai, get() mengembalikan nilai terakhir. <🎜><🎜><🎜><🎜><🎜><🎜>kemas kini()<🎜><🎜><🎜><🎜>Parameter boleh menjadi QueryDict atau kamus standard. Tidak seperti kaedah kemas kini kamus standard, kaedah ini menambah item kamus dan bukannya menggantikannya: <🎜>
>>> q = QueryDict('a=1&a=2&a=3')

>>> q.lists()

[('a', ['1', '2', '3'])]
<🎜><🎜><🎜><🎜><🎜>item()<🎜><🎜><🎜> <🎜 > adalah sedikit berbeza daripada kaedah item() kamus standard Kaedah ini menggunakan logik nilai tunggal __getitem__():<🎜>rrreee<🎜><🎜><🎜><🎜><🎜>nilai()< 🎜> <🎜><🎜><🎜> berbeza sedikit daripada kaedah values() kamus standard Kaedah ini menggunakan __getitem__():<🎜><🎜><🎜><🎜><🎜>

Selain itu, QueryDict juga mempunyai beberapa kaedah, seperti yang ditunjukkan dalam jadual berikut:

Kaedah Penerangan
Kaedah Penerangan
方法描述

copy()

返回对象的拷贝,内部实现是用Python标准库的copy.deepcopy()。该拷贝是mutable(可更改的) — 就是说,可以更改该拷贝的值。

getlist(key)

返回和参数key对应的所有值,作为一个Python list返回。如果key不存在,则返回空list。 It's guaranteed to return a list of some sort..

setlist(key,list_)

设置key的值为list_ (unlike __setitem__()).

appendlist(key,item)

添加item到和key关联的内部list.

setlistdefault(key,list)

和setdefault有一点不同,它接受list而不是单个value作为参数。

lists()

和items()有一点不同, 它会返回key的所有值,作为一个list, 例如:

rrreee

urlencode()

返回一个以查询字符串格式进行格式化后的字符串(e.g., "a=2&b=3&b=5").

copy()
<🎜> Mengembalikan salinan objek, dalaman Pelaksanaan menggunakan copy.deepcopy() pustaka standard Python. Salinan boleh berubah—iaitu, nilai salinan boleh diubah. <🎜>
<🎜>getlist(key)<🎜><🎜>Mengembalikan semua nilai yang sepadan dengan kunci parameter sebagai Python kembali senarai. Jika kunci tidak wujud, senarai kosong dikembalikan. Ia dijamin akan mengembalikan senarai sejenis..<🎜>
<🎜>setlist(key,list_)<🎜><🎜> Tetapkan nilai kunci kepada list_ (tidak seperti __setitem__()).<🎜>
<🎜>appendlist(key,item)<🎜> < 🎜>Tambahkan item pada senarai dalaman yang dikaitkan dengan kunci.<🎜>
<🎜>setlistdefault(kunci, senarai)<🎜>< 🎜 >Ia sedikit berbeza daripada setdefault kerana ia menerima senarai dan bukannya satu nilai sebagai parameter. <🎜>
<🎜>lists()<🎜><🎜>Ia berbeza sedikit daripada item(), ia akan mengembalikan semua kekunci Nilai, sebagai senarai, contohnya: <🎜>rrreee
<🎜>urlencode()<🎜><🎜>Mengembalikan pertanyaan rentetan berformat rentetan aksara (cth., "a=2&b=3&b=5").<🎜>
<🎜>