Formulaire Django


Les formulaires HTML sont la méthode classique d'interactivité des sites Web. Ce chapitre présentera comment utiliser Django pour traiter les données de formulaire soumises par les utilisateurs.


Requête HTTP

Le protocole HTTP fonctionne de manière "requête-réponse". Lorsqu'un client envoie une demande, il peut ajouter des données à la demande. En analysant la requête, le serveur peut obtenir les données envoyées par le client et fournir des services spécifiques basés sur l'URL.

Méthode GET

Nous avons créé un fichier search.py ​​​​dans le projet précédent pour recevoir les demandes des utilisateurs :

# -*- 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)

Ajoutez search_form.html dans le répertoire des modèles de formulaire :

<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 Les règles sont modifiées comme suit :

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),
)

Adresse d'accès : http://192.168.45.3:8000/search-form/ et recherche, les résultats sont les suivants :

1044.jpg

1045.jpg

Méthode POST

Nous avons utilisé la méthode GET ci-dessus. L'affichage de la vue et le traitement des demandes sont divisés en deux fonctions.

La méthode POST est plus couramment utilisée lors de la soumission de données. Nous utilisons cette méthode ci-dessous et utilisons une URL et une fonction de traitement pour afficher la vue et traiter la demande en même temps.

Nous créons post.html dans le modèle :

<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>

À la fin du modèle, nous ajoutons une marque rlt pour réserver une place pour les résultats du traitement du tableau.

Il y a aussi une balise {% csrf_token %} derrière le formulaire. Le nom complet de csrf est Cross Site Request Forgery. Il s'agit d'une fonctionnalité fournie par Django pour empêcher les demandes de soumission déguisées. Les formulaires soumis à l'aide de la méthode POST doivent avoir cette balise.

Créez un nouveau fichier search2.py dans le répertoire HelloWorld et utilisez la fonction search_post pour traiter la requête 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 Les règles sont modifiées sous la forme suivante :

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),
)

Accès http://192.168.45.3:8000/search-post/ Les résultats affichés sont les suivants :

1046.jpg

Après avoir complété l'exemple ci-dessus, notre structure de répertoires est :

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

Objet Request

Le premier paramètre de chaque fonction de vue est un objet HttpRequest, comme la fonction hello() suivante :

from django.http import HttpResponse

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

L'objet HttpRequest contient des informations sur l'objet actuel URL de la demande :

Propriétés

Description

chemin

Le chemin complet vers la page demandée, à l'exclusion du nom de domaine, par exemple, "/hello/".

method

Une représentation sous forme de chaîne de la méthode HTTP utilisée dans la requête. Exprimé en majuscules. Par exemple :

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

GET

Un objet de type dictionnaire contenant tous les paramètres HTTP GET. Consultez la documentation QueryDict.

POST

Un objet de type dictionnaire contenant tous les paramètres HTTP POST. Consultez la documentation QueryDict.

Il est également possible que le serveur reçoive une requête POST vide. En d’autres termes, le formulaire soumet la demande via la méthode HTTP POST, mais le formulaire ne contient aucune donnée. Par conséquent, vous ne pouvez pas utiliser l'instruction if request.POST pour déterminer s'il convient d'utiliser la méthode HTTP POST ; utilisez plutôt if request.method == "POST" (voir l'attribut de méthode dans ce tableau).

Remarque : POST n'inclut pas les informations de téléchargement de fichiers. Voir attribut FILES.

REQUEST

Pour plus de commodité, cet attribut est une collection d'attributs POST et GET, mais il a des fonctionnalités spéciales . Recherchez d'abord les attributs POST, puis les attributs GET. Apprenez de $_REQUEST de PHP.

Par exemple, si GET = {"name": "john"} et POST = {"age": '34'}, alors la valeur de REQUEST["name"] est "john", REQUEST ["La valeur de age"] est "34".

Il est fortement recommandé d'utiliser GET et POST, car ces deux attributs sont plus explicites et le code écrit est plus facile à comprendre.

COOKIES

Un objet de dictionnaire Python standard contenant tous les cookies. Les clés et les valeurs sont toutes deux des chaînes. Voir le chapitre 12 pour une explication plus détaillée des cookies.

FILES

Un objet de type dictionnaire contenant tous les fichiers téléchargés. Chaque clé dans FILES est la valeur de l'attribut name dans la balise <input type="file" name="" /> Chaque valeur dans FILES est également un objet de dictionnaire Python standard, contenant les trois clés suivantes : <🎜. >

  • filename : nom du fichier téléchargé, représenté par une chaîne Python

  • content-type : type de contenu du fichier téléchargé

  • contenu : le contenu original du fichier téléchargé

Remarque : uniquement lorsque la méthode de requête est POST et que la page de requête <form> " L'attribut ne contient que les données des FICHIERS. Sinon, FILES est un dictionnaire vide.

META

Un dictionnaire contenant toutes les informations d'en-tête HTTP disponibles. Par exemple :

  • CONTENT_LENGTH

  • CONTENT_TYPE

  • QUERY_STRING : chaîne de requête brute non analysée

  • REMOTE_ADDR : adresse IP du client

  • REMOTE_HOST : nom d'hôte du client

  • SERVER_NAME : nom d'hôte du serveur

  • SERVER_PORT : port du serveur

Ces en-têtes dans META sont préfixés par HTTP_ comme clé, par exemple :

  • HTTP_ACCEPT_ENCODING

  • HTTP_ACCEPT_LANGUAGE

  • HTTP_HOST : informations d'en-tête de l'hôte HTTP envoyées par le client

  • HTTP_REFERER : page de référence

  • HTTP_USER_AGENT : chaîne de l'agent utilisateur du client

  • HTTP_X_BENDER : informations d'en-tête X-Bender

user

est un objet django.contrib.auth.models.User, représentant la connexion actuelle des utilisateurs.

Si l'utilisateur qui accède n'est pas actuellement connecté, l'utilisateur sera initialisé à une instance de django.contrib.auth.models.AnonymousUser.

Vous pouvez identifier si l'utilisateur est connecté via la méthode is_authenticated() de l'utilisateur :


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

Cet attribut n'est disponible que lorsque l'AuthentificationMiddleware de Django est activé

session

Le seul attribut lisible et inscriptible, représentant l'objet dictionnaire de la session en cours. Cette propriété n'est disponible que lorsque le support de session dans Django est activé. Voir le chapitre 12.

raw_post_data

Données HTTP POST brutes, non analysées. Utile pour le traitement avancé.

L'objet Request possède également quelques méthodes utiles :

< th >Méthode
Description
方法描述
__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__(key)

Renvoyer la valeur clé de GET/POST, obtenir d'abord POST, puis obtenir GET . Lève KeyError si la clé n’existe pas.

C'est ici que nous pouvons accéder à l'objet HttpRequest en utilisant la syntaxe du dictionnaire.

Par exemple, request["foo"] équivaut à request.POST["foo"] puis 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()<🎜><🎜>Vérifiez si request.GET ou request.POST contient la clé spécifiée par le paramètre. <🎜><🎜><🎜><🎜>get_full_path()<🎜><🎜>Renvoie le chemin de la requête contenant la chaîne de requête. Par exemple, "/music/bands/the_beatles/?print=true"<🎜><🎜><🎜><🎜>is_secure()<🎜><🎜>Renvoie True si la demande est sécurisée, c'est-à-dire émise. une requête HTTPS. <🎜><🎜><🎜><🎜><🎜>Objet QueryDict <🎜><🎜>Dans l'objet HttpRequest, les attributs GET et POST sont des instances de la classe django.http.QueryDict. <🎜><🎜>QueryDict est une classe personnalisée de type dictionnaire utilisée pour gérer les situations dans lesquelles une seule clé correspond à plusieurs valeurs. <🎜><🎜>QueryDict implémente toutes les méthodes de dictionnaire standard. Comprend également quelques méthodes uniques : <🎜><🎜><🎜><🎜><🎜>__getitem__<🎜><🎜><🎜><🎜> est un peu différent du traitement standard du dictionnaire, c'est-à-dire si la clé correspond à plusieurs valeurs, __getitem__() renvoie la dernière valeur. <🎜><🎜><🎜><🎜><🎜><🎜>__setitem__<🎜><🎜><🎜><🎜>Définissez la liste de valeurs de la clé spécifiée par le paramètre (une liste Python). Remarque : Il ne peut être appelé que sur un objet QueryDict mutable (c'est-à-dire une copie d'un objet QueryDict généré par copy()).<🎜><🎜><🎜><🎜><🎜><🎜>get() < 🎜><🎜><🎜><🎜>Si key correspond à plusieurs valeurs, get() renvoie la dernière valeur. <🎜><🎜><🎜><🎜><🎜><🎜>update()<🎜><🎜><🎜><🎜>Le paramètre peut être un QueryDict ou un dictionnaire standard. Contrairement à la méthode standard de mise à jour du dictionnaire, cette méthode ajoute des éléments du dictionnaire au lieu de les remplacer : <🎜>
>>> q = QueryDict('a=1&a=2&a=3')

>>> q.lists()

[('a', ['1', '2', '3'])]
<🎜><🎜><🎜><🎜><🎜>items()<🎜><🎜><🎜> <🎜 > est un peu différent de la méthode items() du dictionnaire standard. Cette méthode utilise __getitem__():<🎜>rrreee<🎜><🎜><🎜><🎜><🎜>values()< 🎜> de la logique à valeur unique. <🎜><🎜><🎜> est un peu différent de la méthode values() du dictionnaire standard. Cette méthode utilise __getitem__() de la logique à valeur unique :<🎜><🎜><🎜><🎜><🎜>.

De plus, QueryDict dispose également de quelques méthodes, comme indiqué dans le tableau suivant :

Méthode Description
Méthodes Description
方法描述

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").

copie()
<🎜> Renvoie une copie de l'objet, interne L'implémentation utilise copy.deepcopy() de la bibliothèque standard Python. La copie est modifiable, c'est-à-dire que la valeur de la copie peut être modifiée. <🎜>
<🎜>getlist(key)<🎜><🎜>Renvoie toutes les valeurs correspondant à la clé du paramètre en tant que Python retour de liste. Si la clé n'existe pas, une liste vide est renvoyée. Il est garanti de renvoyer une liste quelconque..<🎜>
<🎜>setlist(key,list_)<🎜><🎜> Définissez la valeur de key sur list_ (contrairement à __setitem__()).<🎜>
<🎜>appendlist(key,item)<🎜> < 🎜>Ajouter un élément à la liste interne associée à la clé.<🎜>
<🎜>setlistdefault(key, list)<🎜>< 🎜 >C'est un peu différent de setdefault dans le sens où il accepte une liste au lieu d'une valeur unique comme paramètre. <🎜>
<🎜>lists()<🎜><🎜>C'est un peu différent de items(), il renverra tout keys Valeur, sous forme de liste, par exemple : <🎜>rrreee
<🎜>urlencode()<🎜><🎜>Renvoie une requête Chaîne de caractères au format chaîne (par exemple, "a=2&b=3&b=5").<🎜>
<🎜>