English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
A view is a web 'type' in the Django application, providing specific functionality and having a specific template. For example, in a blog application, there may be the following views:
Blog home page - displays the last few articles. Enter the 'detail' page - permanent link page for a single item. Archive page - displays all entries for all months of a given year. Monthly archive page - displays all entries for all days of a given month. Daily archive page - displays all entries for a specific day. Comment operations - handle the publication of comments for a given input.
In our poll application, there are the following four views:
The 'index' page of the issue - displays the last few issues. The 'detail' page of the issue - displays the text of an issue without results but with a form to vote. The 'results' page of the issue - displays the results of a specific issue. Voting operations - handle voting on a specific issue for a specific choice.
In Django, web pages and other content are provided by views. Each view is represented by a simple Python function (or method, for class-based views). Django selects a view by examining the majority of the public's favored request URL (more precisely, the part of the URL after the domain).
A URL pattern is a general form of a simple URL - for example: /newsarchive/<year>/<month>/.
Now, let's add some views in polls/views.py. These views are a bit different because they need a parameter:
def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id)
Queste nuove viste vengono aggiunte al modulo polls.urls come segue, chiamata url() come segue, il codice nel file polls/urls.py è il seguente:
from django.conf.urls import url from . import views urlpatterns = [ # es: /polls/ url(r'^$', views.index, name='index'), # es: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), # es: /polls/5/results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), # es: /polls/5/vote/ url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ]
Puoi aprire "polls/34/" nel browser. Esegue il metodo detail() e visualizza qualsiasi contenuto di URL fornito. Riprova ad accedere a "/polls/34/results/" e "/polls/34/vote/" - questo mostrerà i risultati di placeholder e la pagina di voto.
include() può facilmente includere plugin e URL. Poiché polls è nella loro configurazione di URL personale (polls/urls.py), possono essere posizionati in "/polls/", o "/fun_polls/", o "/content/polls/", o in qualsiasi altra radice di percorso, l'applicazione può ancora funzionare.
Di seguito, se l'utente accede a "/polls/34/", ecco cosa succede nel sistema:
Django trova la corrispondenza '^polls/' Poi, Django rimuove il testo corrispondente ("polls/")
E invia il testo rimanente "34/" alla configurazione di URL 'polls.urls' per ulteriori elaborazioni corrispondenti a r'^(?P<question_id>[0-9]+)/$', chiamando la vista detail() come segue:
detail(request=<HttpRequest oggetto>, question_id='34')
question_id='34' è parte di (?P<question_id>[0-9]+) e utilizza i parentesi tonde "" per "catturare" il testo del modello e trasmetterlo come parametro alla funzione di vista; ?P<question_id> definisce il nome del modello da utilizzare per identificare la corrispondenza; e [0-9]+ è un'espressione regolare che corrisponde a una sequenza di numeri (un numero).
Poiché il modello di URL è un'espressione regolare, può essere utilizzato per fare alcune cose, senza limiti. E non c'è bisogno di aggiungere .html all'URL – a meno che non si desideri, in questo caso si può fare così:}}
url(r'^polls/latest\.html$', views.index),
Ogni vista è responsabile di fare una delle due cose: restituire un oggetto HttpResponse che contiene il contenuto della pagina richiesto, o sollevare un'eccezione, come HTTP 404. Modificare il codice del file polls/views.py come segue:
from django.http import HttpResponse from models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] output = ', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output) # Lasciare il resto delle viste (dettagli, risultati, voto) invariato
Ecco un problema: l'informazione di pagina è codificata in modo fisso nel contesto della vista. Se si desidera modificare l'aspetto della pagina, è necessario modificare questo codice Python. Pertanto, utilizziamo il sistema di modelli Django per separare il codice Python utilizzando le viste. polls/templates/polls/index.html Ecco il seguente codice:
{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>Non ci sono sondaggi disponibili.</p> {% endif %}
Ora aggiorniamo la vista首页 polls/views.py utilizzando il seguente modello (codice):
from django.http import HttpResponse from django.template import loader from models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))
Questo codice carica il modello chiama polls/index.html e passingogli il contesto. Il contesto è un dizionario che mappa gli oggetti Python ai nomi delle variabili del modello. Ora visita l'URL (http://127.0.0.1:8000/polls/) per vedere i risultati:
Questa è una convenzione molto comune per caricare il modello, riempire il contesto e restituire l'oggetto HttpResponse. Django fornisce un trucco. Ecco la vista completa di index() che modifica polls/views.py:
from django.shortcuts import render from models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)
Nota che quando si fa questo in tutte le viste, non è necessario importare il caricatore e l'oggetto HttpResponse (mantieni HttpResponse se ci sono ancora i metodi detail, results e vote abbreviati).
Ora, risolviamo questo problema della vista dettagliata - mostrare la pagina del testo della domanda di sondaggio. Aggiungi il codice della vista qui (polls/views.py):
from django.http import Http404 from django.shortcuts import render from models import Question # ... def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("La domanda non esiste") return render(request, 'polls/detail.html', {'question': question})
Attenzione qui: la vista lancia un'eccezione HTTP404, anche se non c'è alcun problema con l'ID della richiesta.
Discuteremo delle modifiche che possiamo apportare a polls/detail.html in seguito, ma se vogliamo utilizzare rapidamente l'esempio sopra, il file polls/templates/polls/detail.html deve contenere solo:
{{question}}
Solleva un errore 404, ora richiediamo un problema inesistente, come: http://127.0.0.1:8000/polls/100/, e il risultato è il seguente:
Un uso comune di get() per sollevare un errore HTTP404 quando l'oggetto non esiste. Django fornisce un trucco. Ecco la vista detail() modificata in polls/views.py:
from django.shortcuts import get_object_or_404, render from models import Question # ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})
La funzione get_object_or_404() accetta un modello Django come primo parametro e una quantità variabile di parametri chiave, che vengono passati alla funzione get() della gestione del modello.
Se l'oggetto non esiste, solleva un HTTP404.
C'è anche la funzione get_list_or_404(), che funziona allo stesso modo di get_object_or_404() – eccetto che utilizza filter() invece del metodo get(). Se la lista è vuota, solleva un HTTP404.
Torniamo alla nostra applicazione polls e alla vista detail(). A causa del problema delle variabili di contesto, il template polls/detail.html sembra così:
<h1>{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul>
Il sistema di modelli utilizza la sintassi di interrogazione per accedere alle proprietà delle variabili. In questo esempio {{question.question_text}},il primo Django cerca davvero nel dizionario dell'oggetto question. Se non lo trova, tenta una ricerca di attributo – se la ricerca dell'attributo fallisce, tenta una ricerca di indice di lista.
Ora testiamo il codice che abbiamo scritto sopra, apri il browser e vai a: http://127.0.0.1:8000/polls/5/ per ottenere i risultati seguenti:
Ricorda, quando linkiamo un problema in polls/index.html, la parte hard-coded del link è questa:
<li><a href="/polls/{{question.id}}/">{{question.question_text}}</a></li>
Il problema di questo metodo di lavoro, che è strettamente耦合ato e hard-coded, è che utilizza molte template per cambiare l'URL del progetto. Tuttavia, poiché il modulo polls.urls definisce il parametro di nome della funzione url(), puoi rimuovere la dipendenza specifica dell'URL configurato utilizzando il tag di modello {% url %}:
<li><a href="{etail'question.id%}">{{question.question_text}}</a></li>
Questo funzionamento è possibile grazie alla definizione delle URL specifiche nel modulo polls.urls. Puoi vedere esattamente come è definito il nome dell'URL 'detail' come segue:
... # il valore 'name' chiamato dal tag di modello {% url %} url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), ...
Se vuoi cambiare l'URL della vista dettagliata del voto in un altro, magari come polls/specifics/12/, sostituiscilo nel polls/urls.py:
... # aggiunto la parola 'specifics' url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'), ...
Questo tutorial ha un solo'applicazione - polls. In un progetto Django reale, possono esserci cinque, dieci, venti o anche più applicazioni. Come fa Django a distinguere i loro URL? Ad esempio, l'applicazione di voto ha una vista dettagliata, quindi potrebbe esserci la stessa applicazione in un progetto di blog. Come usare il tag di modello {% url %} per far sapere a Django quali applicazioni hanno una vista per creare un URL?
La risposta è aggiungere lo spazio nome alla configurazione URL. Nel file polls/urls.py, vai avanti e aggiungi il nome dell'applicazione per impostare lo spazio nome dell'applicazione, apri polls/urls.py:
from django.conf.urls import url from . import views app_name = 'polls' urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ]
Ora modifica il modello 'polls/index.html', apri il file 'polls/templates/polls/index.html' e aggiungi il seguente codice:
<li><a href="{etail'question.id%}">{{question.question_text}}</a></li>
Fare in modo che punti alla vista nel namespace 'detail', aprire il file 'polls/templates/polls/index.html' come segue:
<li><a href="{olls:detail'question.id%}">{{question.question_text}}</a></li>