Dies ist ein Material für Lernsitzungen. Ich werde es erklären, während ich dem Tutorial von django1.8 folge. https://docs.djangoproject.com/en/1.8/intro/tutorial04/
Da Version 1.4 die neueste Version des offiziellen japanischen Dokuments ist, gibt es einige Unterschiede, aber der allgemeine Ablauf ist der gleiche. Es ist daher eine gute Idee, ihn zu lesen. http://django-docs-ja.readthedocs.org/en/latest/intro/tutorial04.html
Tutorial 1 Tutorial 2 Tutorial 3
Quelle: 99b01e3
→ 49d2e35
Schreiben wir zunächst "detail.html" für die Abstimmung gemäß dem ursprünglichen Tutorial neu, damit Sie abstimmen können.
polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'poll_vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
Da die URL nicht als Leerzeichen bezeichnet wird, wird "polls: vote" in "poll_vote" umgeschrieben.
Ich habe noch keine URL mit dem Namen polls_vote definiert. Wenn ich den Browser so öffne, wie er ist, tritt ein Fehler auf. Lassen Sie uns vorerst urls.py und views.py umschreiben und nur die Haut vorbereiten.
polls/views.py
...
def vote(request, pk):
pass
polls/urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'(?P<pk>\d+)/$', views.detail, name='poll_detail'),
url(r'(?P<pk>\d+)/vote$', views.vote, name='poll_vote'),
]
Überprüfen Sie den Detailbildschirm im Browser.
Es ist ein gutes Gefühl. Da die Abstimmungsfunktion nicht implementiert ist, tritt übrigens ein Fehler auf, wenn Sie die Taste drücken.
Lassen Sie uns ein wenig zurückgehen und den Code in HTML erklären. Das Tag "{% if%}" wurde noch nicht angezeigt, aber error_message wird in derselben Bedeutung übergeben. Wenn ein Wert vorhanden ist, wird der Block bis "{% endif%}" ausgegeben.
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
Das Tag "{% csrf_token%}" ist, wie der Name schon sagt, ein Tag zum Festlegen des CSRF-Tokens.
Es muss im Tag <form method =" post ">
festgelegt werden.
Wenn Sie vergessen, dieses Tag festzulegen, tritt eine CSRF-Ausnahme auf.
[wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3% 83% 88% E3% 83% AA% E3% 82% AF% E3% 82% A8% E3% 82% B9% E3% 83% 88% E3% 83% 95% E3% 82% A9% E3% 83% Von BC% E3% 82% B8% E3% 82% A7% E3% 83% AA)
Fälschungen von standortübergreifenden Anforderungen (Abkürzung: CSRF oder XSRF) sind eine der Angriffsmethoden im WWW.
Zu den besonderen Schäden zählen unbeabsichtigtes Posten am Schwarzen Brett und Einkaufen in Online-Shops. Wenn die Webschnittstelle von Informationsgeräten wie Routern und WLANs angegriffen werden soll, besteht außerdem die Sorge, dass die Einstellungen dieser Geräte ohne Erlaubnis geändert werden können.
Kurz gesagt. Dies soll sicherstellen, dass die Daten von der legitimen Eingabeseite gesendet wurden. Um zu verhindern, dass Daten vom POST von anderen Sites geworfen werden, wird das Token in die Eingabeseite eingebettet.
Quelle: 49d2e35
→ 274bd82
Lassen Sie uns die Abstimmungsfunktion bearbeiten. Trotzdem ist es fast eine Kopie des ursprünglichen Tutorials. Das Umleitungsziel ist die Ergebnisseite in der Kopffamilie, aber dieses Mal versuche ich, sie zum Listenbildschirm zu überspringen.
polls/views.py
from django.shortcuts import redirect
from .models import Choice
...
def vote(request, pk):
question = get_object_or_404(Question, pk=pk)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
return redirect('index')
Eine kleine Code-Erklärung.
selected_choice = question.choice_set.get(pk=request.POST['choice'])
Es gibt eine Beschreibung von choice_set
, einem Manager zum Bearbeiten des Choice-Modells, das eine Beziehung zum Fragenobjekt hat.
question.choice_set
und Choice.objects.filter (question = question)
haben die gleiche Bedeutung.
Wenn Sie die Bedeutung nicht verstehen, waschen Sie sie bitte leicht.
Der gebuchte Wert wird in "request.POST" in einem wörterbuchartigen Format gespeichert. Da der Name-Attributwert des Eingabe-Tags "Auswahl" ist, können Sie ihn mit request.POST ["Auswahl"] auswählen.
In der nächsten Zeile
except (KeyError, Choice.DoesNotExist):
Hier schreibe ich die Verarbeitung, wenn keine Auswahleingabe vorhanden ist (KeyError) und wenn ein anderer Wert als die Auswahl ausgelöst wird (DoesNotExist).
In diesem Beispiel wird error_message eingefügt und die Eingabeseite erneut angezeigt.
Die Klausel "else:" wird eingegeben, wenn die Auswahl für die Buchung erfolgreich getroffen wurde. Die Stimmen (Anzahl der Beiträge) der ausgewählten Auswahl werden erhöht und gespeichert, und der Sprung zur Listenseite wird ausgeführt.
Im Original-Tutorial
return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
Obwohl es so geschrieben ist, wird hier die Umleitungsfunktion verwendet. Was Sie tun, ist genau das gleiche.
Quelle: 274bd82
→ 4ecb885
Lassen Sie uns eine richtige Ergebnisseite anstelle eines Listenbildschirms erstellen. Wie üblich ist HTML ein Kopieren und Einfügen aus dem ursprünglichen Tutorial.
polls/templates/polls/results.html
<html>
<body>
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'poll_detail' question.id %}">Vote again?</a>
</body>
</html>
Fügen Sie als Nächstes die Ergebnisfunktion zu views.py hinzu. Der Inhalt entspricht fast dem Detail, nur der HTML-Pfad wird geändert.
polls/views.py
def results(request, pk):
obj = get_object_or_404(Question, pk=pk)
return render(request, 'polls/results.html', {
'question': obj,
})
Bearbeiten Sie abschließend die URL und verbinden Sie die Ansichten, um den Vorgang abzuschließen.
polls/urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'(?P<pk>\d+)/$', views.detail, name='poll_detail'),
url(r'(?P<pk>\d+)/vote$', views.vote, name='poll_vote'),
url(r'(?P<pk>\d+)/results$', views.results, name='poll_results'),
]
Die Ergebnisseite ist fertig.
Da es nach dem Posten zur Listenseite springen sollte, korrigieren wir es so, dass es zur Ergebnisseite springt. Beachten Sie, dass "poll_results" im Gegensatz zur Listenseite ein Argument erfordert.
polls/views.py
def vote(request, pk):
...
return redirect('poll_results', pk)
Jetzt können Sie nach dem Posten zur Ergebnisseite springen.
Dokument → https://docs.djangoproject.com/de/1.8/intro/tutorial04/#use-generic-views-less-code-is-better Klassenbasierte View-Dokumentation → https://docs.djangoproject.com/de/1.8/topics/class-based-views/
Informationen zu häufig verwendeten Ansichten wie Modelllistenanzeige, Detailanzeige, Vorlagenspezifikation usw. django bietet eine klassenbasierte Allzweckansicht.
Der "Index", "Detail" und "Ergebnisse" in views.py, die ich jetzt schreibe, haben eine kleine Anzahl von Zeilen, so dass es schwierig sein mag, die Vorteile zu spüren, aber Form ist wie Abstimmung involviert und ein wenig kompliziert. Wenn es darum geht, wird es ein sehr mächtiges Werkzeug.
Da die Form-Klasse im Tutorial noch nicht erwähnt wurde, habe ich diesmal die Quelle nicht geändert. Ich werde es nur vorstellen, während ich mir das Original-Tutorial ansehe.
Die klassenbasierte Ansichtskonvertierung wird im nächsten (oder nächsten) Lernprogramm durchgeführt. Wenn Sie also nicht interessiert sind, überspringen Sie es bitte.
TemplateView
Obwohl es nicht im ursprünglichen Tutorial enthalten ist, ist es eine einfache Ansicht, in der nur die zu verwendende Vorlage festgelegt wird. Sie können es einfach verwenden, indem Sie festlegen, welche Vorlage verwendet werden soll. Überschreiben Sie die Methode "get_context", um festzulegen, dass das Wörterbuch an die Vorlage übergeben wird.
Alle klassenbasierten Ansichten müssen mit der Methode as_view ()
funktionalisiert werden, da die Ansichtsfunktion an url übergeben werden muss.
app/views.py
from django.views.generic import TemplateView
class Index(TemplateView):
template_name = 'app/index.html'
index = Index.as_view()
Es ist so.
Klasseneigenschaften wie template_name können auch zum Zeitpunkt von as_view übergeben werden. Mit anderen Worten, ohne views.py zu ändern, wenden Sie es wie folgt in urls.py an.
app/urls.py
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='app/index.html'), name='app_index'),
]
DetailView
Geben Sie zusätzlich zu der zu verwendenden Vorlage an, welches Modell verwendet werden soll.
app/views.py
from django.views.generic import DetailView
from .model import AppModel
class Detail(DetailView):
template_name = 'app/detail.html'
model = AppModel
detail = Detail.as_view()
Natürlich kann diese Klasse auch direkt in urls.py geschrieben werden.
Die Vorlage heißt "Objekt" (und der Modellname in Kleinbuchstaben, z. B. "App-Modell").
Das erfasste Objekt wird übergeben.
Standardmäßig wird es von urls.py mit dem Namen pk
aufgerufen.
Wenn das Objekt nicht gefunden wird, wird Http404 ausgelöst.
ListView
Detail ist ein einzelnes Objekt eines Modells, während ListView mehrere Objekte zurückgibt. Welches Objekt zurückgegeben werden soll, wird durch Übergeben der Eigenschaft "queryset" oder Überschreiben der Methode "get_queryset" angegeben.
app/views.py
from django.views.generic import ListView
from .model import AppModel
class Index(ListView):
template_name = 'app/index.html'
queryset = AppModel.objects.all()
Diese Klasse verfügt über verschiedene Anpassungselemente wie Paging und Reihenfolge.
--
Im ursprünglichen Tutorial wird der Test aber als nächstes erklärt, aber Im nächsten Tutorial werde ich einen Abstecher machen und die Form-Klasse und die ModelForm-Klasse erklären.
Recommended Posts