Django-Formulare

HTML-Formulare sind eine klassische Möglichkeit, Interaktivität auf Websites zu erreichen. In diesem Kapitel wird vorgestellt, wie man mit Django von Benutzern übermittelte Formulardaten verarbeitet.


HTTP-Anfrage

Das HTTP-Protokoll arbeitet nach dem „Anfrage-Antwort“-Muster. Wenn ein Client eine Anfrage sendet, kann er Daten an die Anfrage anhängen. Durch das Auswerten der Anfrage kann der Server die vom Client gesendeten Daten abrufen und basierend auf der URL bestimmte Dienste bereitstellen.

GET-Methode

Erstellen Sie in unserem vorherigen Projekt eine search.py-Datei, um Benutzeranfragen zu empfangen:

/HelloWorld/HelloWorld/search.py Code der Datei:

from django.http import HttpResponse from django.shortcuts import render # Formular def search_form(request): return render(request, 'search_form.html') # Anfragedaten empfangen def search(request): request.encoding='utf-8' if 'q' in request.GET and request.GET['q']: message = 'Der Inhalt, nach dem Sie gesucht haben, ist:' + request.GET['q'] else: message = 'Sie haben ein leeres Formular übermittelt' return HttpResponse(message)

Fügen Sie das Formular search_form.html im Verzeichnis templates hinzu:

Code der Datei /HelloWorld/templates/search_form.html:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Beispiel (example.com)</title> </head> <body> <form action="/search/" method="get"> <input type="text" name="q"> <input type="submit" value="Suchen"> </form> </body> </html>

Ändern Sie die urls.py-Regeln in die folgende Form:

/HelloWorld/HelloWorld/urls.py Datei-Code:

from django.conf.urls import url from . import views,testdb,search urlpatterns = [ url(r'^hello/$', views.example), url(r'^testdb/$', testdb.testdb), url(r'^search-form/$', search.search_form), url(r'^search/$', search.search), ]

Zugriffsadressehttp://127.0.0.1:8000/search-form/Und suchen, die Ergebnisse sind wie folgt:

POST-Methode

Oben haben wir die GET-Methode verwendet, und die Anzeige der Ansicht und die Verarbeitung der Anfrage werden von zwei separaten Funktionen übernommen.

Beim Übermitteln von Daten wird die POST-Methode häufiger verwendet. Im Folgenden verwenden wir diese Methode und nutzen eine einzelne URL und Handler-Funktion, um sowohl die Ansicht anzuzeigen als auch die Anfrage zu verarbeiten.

Wir erstellen post.html in templates:

Der Code der Datei /HelloWorld/templates/post.html:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Beispiel (example.com)</title> </head> <body> <form action="/search-post/" method="post"> {% csrf_token %} <input type="text" name="q"> <input type="submit" value="Suchen"> </form> <p>{{ rlt }}</p> </body> </html>

Am Ende des Templates fügen wir einen rlt-Marker hinzu, um eine Position für das Ergebnis der Formularverarbeitung zu reservieren.

Nach dem Formular gibt es außerdem ein{% csrf_token %}Tag. CSRF steht für Cross Site Request Forgery. Dies ist eine von Django bereitgestellte Funktion, um getarnte Anfrageübermittlungen zu verhindern. Formulare, die mit der POST-Methode übermittelt werden, müssen dieses Tag enthalten.

Erstellen Sie eine neue Datei search2.py im Verzeichnis HelloWorld und verwenden Sie die Funktion search_post, um POST-Anfragen zu verarbeiten:

/HelloWorld/HelloWorld/search2.py Datei-Code:

# -*- coding: utf-8 -*- from django.shortcuts import render from django.views.decorators import csrf # POST-Anfragedaten empfangen def search_post(request): ctx ={} if request.POST: ctx['rlt'] = request.POST['q'] return render(request, "post.html", ctx)

Ändern Sie die urls.py-Regeln in die folgende Form:

/HelloWorld/HelloWorld/urls.py Datei-Code:

from django.conf.urls import url from . import views,testdb,search,search2 urlpatterns = [ url(r'^hello/$', views.hello), url(r'^testdb/$', testdb.testdb), url(r'^search-form/$', search.search_form), url(r'^search/$', search.search), url(r'^search-post/$', search2.search_post), ]

Besuchen Siehttp://127.0.0.1:8000/search-post/Die angezeigten Ergebnisse sind wie folgt:

Nach Abschluss des obigen Beispiels sieht unsere Verzeichnisstruktur wie folgt aus:

HelloWorld
|-- HelloWorld
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- search.py
|   |-- search.pyc
|   |-- search2.py
|   |-- search2.pyc
|   |-- settings.py
|   |-- settings.pyc
|   |-- testdb.py
|   |-- testdb.pyc
|   |-- urls.py
|   |-- urls.pyc
|   |-- views.py
|   |-- views.pyc
|   |-- wsgi.py
|   `-- wsgi.pyc
|-- TestModel
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- admin.py
|   |-- admin.pyc
|   |-- apps.py
|   |-- migrations
|   |   |-- 0001_initial.py
|   |   |-- 0001_initial.pyc
|   |   |-- __init__.py
|   |   `-- __init__.pyc
|   |-- models.py
|   |-- models.pyc
|   |-- tests.py
|   `-- views.py
|-- db.sqlite3
|-- manage.py
`-- templates
    |-- base.html
    |-- hello.html
    |-- post.html
    `-- search_form.html

Request-Objekt

Der erste Parameter jeder View-Funktion ist ein HttpRequest-Objekt, wie die unten stehende Funktion example():

from django.http import HttpResponse

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

Das HttpRequest-Objekt enthält einige Informationen über die aktuelle Anfrage-URL:

Eigenschaft

Beschreibung

path

Der vollständige Pfad der angeforderten Seite, ohne den Domainnamen — zum Beispiel "/hello/".

method

Die String-Darstellung der in der Anfrage verwendeten HTTP-Methode. Darstellung in Großbuchstaben. Zum Beispiel:

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

GET

Ein dictionary-ähnliches Objekt, das alle HTTP-GET-Parameter enthält. Siehe die QueryDict-Dokumentation.

POST

Ein dictionary-ähnliches Objekt, das alle HTTP-POST-Parameter enthält. Siehe die QueryDict-Dokumentation.

Es ist möglich, dass der Server eine leere POST-Anfrage empfängt. Das heißt, das Formular übermittelt eine Anfrage über die HTTP-POST-Methode, aber das Formular enthält möglicherweise keine Daten. Daher können Sie die Anweisung if request.POST nicht verwenden, um festzustellen, ob die HTTP-POST-Methode verwendet wird; Sie sollten if request.method == "POST" verwenden (siehe das method-Attribut in dieser Tabelle).

Hinweis: POST enthält keine Informationen zum Dateiupload. Siehe das FILES-Attribut.

REQUEST

Der Einfachheit halber ist dieses Attribut eine Kombination aus den Attributen POST und GET, es hat jedoch ein besonderes Verhalten: Es sucht zuerst nach dem POST-Attribut und dann nach dem GET-Attribut. Es ist PHPs $_REQUEST nachempfunden.

Zum Beispiel: Wenn GET = {"name": "john"} und POST = {"age": '34'}, dann ist der Wert von REQUEST["name"] "john" und der Wert von REQUEST["age"] "34".

Es wird dringend empfohlen, GET und POST zu verwenden, da diese beiden Attribute expliziter sind und der geschriebene Code leichter zu verstehen ist.

COOKIES

Ein Standard-Python-Dictionary-Objekt, das alle Cookies enthält. Sowohl Schlüssel als auch Werte sind Zeichenketten.

FILES

Ein Dictionary-ähnliches Objekt, das alle hochgeladenen Dateien enthält. Jeder Schlüssel in FILES ist der Wert des name-Attributs im <input type="file" name="" />-Tag. Jeder Wert in FILES ist ebenfalls ein standardmäßiges Python-Dictionary-Objekt, das die folgenden drei Schlüssel enthält:

  • filename: der Name der hochgeladenen Datei, dargestellt als Python-String.
  • content-type: Inhaltstyp der hochgeladenen Datei
  • content: der Rohinhalt der hochgeladenen Datei.

Hinweis: FILES enthält nur Daten, wenn die Request-Methode POST ist und das <form> auf der Anfrageseite das Attribut enctype="multipart/form-data" hat. Andernfalls ist FILES ein leeres Dictionary.

META

Ein Dictionary, das alle verfügbaren HTTP-Header-Informationen enthält. Zum Beispiel:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • QUERY_STRING: die ungeparste rohe Abfragezeichenfolge.
  • REMOTE_ADDR: Client-IP-Adresse
  • REMOTE_HOST: Client-Hostname
  • SERVER_NAME: Server-Hostname
  • SERVER_PORT: Server-Port

Diese Header in META werden mitHTTP_präfixiert. Der Teil vor dem Doppelpunkt (:) ist der Schlüssel, und der Teil danach ist der Wert, zum Beispiel:

  • HTTP_ACCEPT_ENCODING
  • HTTP_ACCEPT_LANGUAGE
  • HTTP_HOST: die vom Client gesendeten HTTP-Host-Header-Informationen.
  • HTTP_REFERER: verweisende Seite
  • HTTP_USER_AGENT: User-Agent-Zeichenfolge des Clients
  • HTTP_X_BENDER: X-Bender-Header-Informationen

user

ist ein django.contrib.auth.models.User-Objekt, das den aktuell angemeldeten Benutzer repräsentiert.

Wenn der zugreifende Benutzer aktuell nicht angemeldet ist, wird user als eine Instanz von django.contrib.auth.models.AnonymousUser initialisiert.

Sie können die Methode is_authenticated() des Benutzers verwenden, um festzustellen, ob der Benutzer angemeldet ist:

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

Dieses Attribut ist nur verfügbar, wenn AuthenticationMiddleware in Django aktiviert ist.

session

Das einzige Lese-/Schreib-Attribut, ein Dictionary-Objekt, das die aktuelle Sitzung repräsentiert. Dieses Attribut ist nur verfügbar, wenn Djangos Session-Unterstützung aktiviert ist.

raw_post_data

Die rohen, nicht geparsten HTTP-POST-Daten. Dies ist für fortgeschrittene Verarbeitung nützlich.

Das Request-Objekt bietet außerdem einige nützliche Methoden:

MethodenBeschreibung
__getitem__(key) Gibt den Schlüssel-Wert aus GET/POST zurück, wobei zuerst POST und dann GET berücksichtigt wird. Löst KeyError aus, wenn der Schlüssel nicht existiert.
Dies ermöglicht es uns, auf das HttpRequest-Objekt mit Dictionary-Syntax zuzugreifen.
Zum Beispiel entspricht request["foo"] der Operation: zuerst request.POST["foo"], dann request.GET["foo"].
has_key() Prüft, ob request.GET oder request.POST den durch den Parameter angegebenen Schlüssel enthält.
get_full_path() Gibt den Anforderungspfad einschließlich der Abfragezeichenfolge zurück. Zum Beispiel "/music/bands/the_beatles/?print=true"
is_secure() Gibt True zurück, wenn die Anfrage sicher ist, d. h. wenn sie über HTTPS erfolgt ist.

QueryDict-Objekt

Im HttpRequest-Objekt sind die Attribute GET und POST Instanzen der Klasse django.http.QueryDict.

QueryDict ist eine benutzerdefinierte, wörterbuchähnliche Klasse, die verwendet wird, um die Situation zu behandeln, in der ein einzelner Schlüssel mehreren Werten entspricht.

QueryDict implementiert alle Standard-Dictionary-Methoden. Es enthält außerdem einige spezielle Methoden:

Methoden Beschreibung

__getitem__

Es gibt einen Unterschied zur Standard-Wörterbuchbehandlung: Wenn ein Schlüssel mehreren Werten entspricht, gibt __getitem__() den letzten Wert zurück.

__setitem__

Legt die Werteliste (eine Python-Liste) für den angegebenen Schlüssel fest. Hinweis: Kann nur auf einem veränderlichen QueryDict-Objekt aufgerufen werden (d. h. einer Kopie eines QueryDict-Objekts, die über copy() erstellt wurde).

get()

Wenn ein Schlüssel mehreren Werten entspricht, gibt get() den letzten Wert zurück.

update()

Der Parameter kann ein QueryDict oder ein Standardwörterbuch sein. Anders als die update-Methode des Standardwörterbuchs fügt diese Methode Wörterbucheinträge hinzu, anstatt sie zu ersetzen:

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

Es gibt einen Unterschied zur items()-Methode des Standardwörterbuchs: Diese Methode verwendet die Einzelwertlogik von __getitem__():

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

>>> q.items()

[('a', '3')]

values()

Es gibt einen Unterschied zur values()-Methode des Standardwörterbuchs: Diese Methode verwendet die Einzelwertlogik von __getitem__():

Darüber hinaus hat QueryDict auch einige Methoden, wie in der folgenden Tabelle gezeigt:

Methoden Beschreibung

copy()

Gibt eine Kopie des Objekts zurück, intern implementiert mit der Python-Standardbibliothek copy.deepcopy(). Diese Kopie ist veränderbar — das heißt, die Werte der Kopie können geändert werden.

getlist(key)

Gibt alle Werte zurück, die dem Parameter key entsprechen, als Python-Liste. Wenn der key nicht existiert, wird eine leere Liste zurückgegeben. Es ist garantiert, dass eine Liste irgendeiner Art zurückgegeben wird.

setlist(key,list_)

Setzt den Wert von key auf list_ (im Gegensatz zu __setitem__()).

appendlist(key,item)

Fügt der internen Liste, die dem key zugeordnet ist, ein Element hinzu.

setlistdefault(key,list)

Es gibt einen Unterschied zu setdefault: Es akzeptiert eine Liste als Parameter statt eines einzelnen Werts.

lists()

Es gibt einen Unterschied zu items(): Es gibt alle Werte für den key als Liste zurück, zum Beispiel:

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

>>> q.lists()

[('a', ['1', '2', '3'])]

urlencode()

Gibt eine Zeichenkette zurück, die als Query-String formatiert ist (zum Beispiel: "a=2&b=3&b=5").

Weitere Erweiterungen