Ab Letztes Mal fahren wir mit dem Django-Tutorial fort. Dieses Mal werde ich über die klassenbasierte Ansicht sprechen, die ein wichtiger Punkt bei der Verwendung von Django ist.
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls: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>
Angenommen, Sie möchten ein solches Formular erstellen.
Es ist ein Formular, das eine Antwort mit einem Optionsfeld für eine bestimmte Frage vorbereitet, überprüft und per Post sendet.
{{forloop.counter}}
ist die Anzahl der Schleifen für {% zur Auswahl in question.choice_set.all%}
.
Die tatsächliche Notation wäre beispielsweise "<input type =" radio "name =" choice "id =" choice1 "value =" 1 ">".
Werfen wir einen Blick auf die Ansicht dazu.
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from .models import Choice, Question
# ...
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
# selected_choice.votes += 1
#Der obige Code verursacht Konfliktprobleme, also F.(Spaltenname)Verwenden Sie die Methode.
selected_choice.votes = F('votes') + 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Was sich gegenüber der vorherigen Zeit geändert hat, ist, dass die Objekte "HttpResposeRedirect" und "reverse" importiert wurden.
Ersteres ist eine Methode zum Umleiten, und letzteres reverse ()
Methode ist eine Methode, die eine URL zurückgibt und die URL über den in urls.py festgelegten benannten Pfad aufruft. Zum Beispiel im obigen Fall
Die URL / polls / results
wird zurückgegeben, aber Sie können die URL / polls / 1 / results
zurückgeben, indem Sie question.id als Argument angeben.
Wenn Sie den Inhalt der Abstimmungsfunktion bis zum letzten Mal selbst verstehen, ist es nicht so schwer zu verstehen, was Sie tun.
Weisen Sie der Variablen zunächst eine Instanz zu. Da es sich um eine "get_object_or_404" -Methode handelt, handelt es sich um eine Instanz der Daten des entsprechenden Primärschlüssels aus dem "Question" -Modell.
Wir werden dies als Ausnahme mit dem Muster "try-catch-else" behandeln.
Basierend auf den vom Formular gesendeten POST-Daten wird zunächst die Methode "get ()" verwendet, um die Daten aus der Datenbank abzurufen.
Mit request.POST
können Sie auf die mit dem angegebenen Schlüssel gesendeten Daten zugreifen.
In diesem Fall von "request.POST [" choice "] bedeutet dies beispielsweise, auf die Daten zuzugreifen, deren" name "-Attribut" choice "ist.
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
Es wird dieser Teil sein.
Diesmal handelt es sich also um ein Formular mit einem Optionsfeld. In der Schleife von "for" gibt es also einige Auswahlmöglichkeiten. Da jedoch nur eine Daten gesendet werden müssen, wird der Wert "value" dieser Auswahl herausgenommen und in "pk" umgewandelt Werden. Übrigens, wenn es mehrere gleiche Namensattribute wie Kontrollkästchen gibt, verwenden Sie bitte getlist () anstelle von get (). Aus leisem Gespräch wird beispielsweise "question.choice_set.get (pk = request.POST ['choice'])" zu "question.choice_set.get (pk = 1)", dh Daten mit Primärschlüssel 1 sind "choice" Es wird aus dem Modell heraus durchsucht und der Variablen als Instanz zugewiesen. Wenn es sicher abgerufen werden kann, springt es zu "else". Wenn es nicht abgerufen werden kann, wird es als Ausnahme von "KeyError" behandelt, und die Fehlermeldung wird von der Methode "render ()" zurückgegeben und an den Formularbildschirm zurückgegeben. Der Vorgang von "else" besteht darin, die Anzahl der Stimmen zu erhöhen, sie in der Datenbank zu aktualisieren und zum Abstimmungsergebnisbildschirm umzuleiten. Erstellen wir nun eine Vorlage für die Abstimmungsergebnisse.
<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 'polls:detail' question.id %}">Vote again?</a>
Der Teil von "vote {{choice.votes | pluralize}}" ist der Ausdruck, dass, wenn der Wert auf der linken Seite von "pluiralize" eine Pluralform ist, ein Suffix zurückgegeben wird, das die Pluralform angibt. Wenn in diesem Fall beispielsweise "choice.votes" 2 ist, wird "stimme" zu "Stimmen".
Nun, ich habe bisher verschiedene "Ansichten (Controller)" geschrieben, aber "Django" hat eine eingebaute sogenannte Allzweckansicht, die als klassenbasierte Ansicht bezeichnet wird.
view
hat die Aufgabe, Daten und URL
mit der Vorlage zu verbinden, obwohl dies bisher geschehen ist
-Erstelle und zeige eine Liste mit filter ()
an
Ich denke, dass ein solcher Prozess viele Male herauskam und ich schrieb jedes Mal "view".
Eine allgemeine Ansicht ist ein System, das im Voraus geeignete Standardwerte für das Modell und das Formular festlegt, damit Sie diese Verarbeitung nicht viele Male schreiben müssen.
Übrigens, wie Sie an der Tatsache sehen können, dass es klassenbasiert ist, wird die allgemeine Ansicht in Django
von der Klasse bereitgestellt.
Es scheint, dass es auch eine Funktionsbasis gibt.
Werfen wir einen Blick auf die vorherige Ansicht.
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
# Create your views here.
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)
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
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):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Als nächstes ist hier die neue "Ansicht" zu schreiben
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from .models import Question, Choice
# Create your views here.
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
#Zugriff auf POST-Daten. Dieses Mal wird die ID der Option, die über das Optionsfeld im Formular ausgewählt wurde, als Zeichenfolge zurückgegeben und der Variablen zugewiesen.
selected_choice = question.choice_set.get(pk=request.POST['choice'])
#Geben Sie den Schlüsselfehler in der Ausnahmespezifikation an. Ausnahmebehandlung, wenn keine Wahl besteht.
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', { 'question':question, 'error_message':"You didn`t select a choice.",})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
#Weiterleitungsverarbeitung in Django. umkehren()In URLs.Rufen Sie die URL über den in py festgelegten benannten Pfad auf. Sie können eine bestimmte Seite angeben, indem Sie das Argument angeben.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Sie können sehen, dass es ganz anders ist. Importieren Sie zunächst das generische Objekt aus dem Modul "django.views". Es kann auch importiert und für jede klassenbasierte Ansicht verwendet werden, z. B. "aus django.views.generic import ListView". In diesem Fall wäre das Argument "ListView" anstelle von "generic.ListView". Und wie oben erwähnt, werden wir, da es sich um eine klassenbasierte Ansicht handelt, das, was zuvor als Funktion geschrieben wurde, in eine Klasse umschreiben und jede klassenbasierte Ansicht erben und verwenden. Zum Beispiel sieht es aus wie "Klasse IndexView (generic.ListView):". Geben Sie die allgemeine Ansicht an, die Sie als Argument verwenden möchten, da sie erbt. Natürlich kann die Vererbung auch überschrieben werden. Schauen wir uns jeden an.
Listview
"Listenansicht" ist eine Ansicht zum Anzeigen einer Liste von Objekten. Mit anderen Worten, es kann beim Erstellen einer Listenseite verwendet werden.
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
Wenn Sie es tatsächlich verwenden, wird es wie oben geschrieben.
Normalerweise ist es wichtig, das Modell anzugeben, wenn Sie die klassenbasierte Ansicht verwenden. Sie können jedoch auch die Methode von "queryset ()" angeben.
Zum Beispiel möchten wir oben, anstatt nur die Liste der Modelle anzuzeigen, die Liste in Schritten von 5 anzeigen, also geben wir mit query set ()
an, anstatt das Modell anzugeben.
Geben Sie anschließend die Vorlage des Überbrückungsziels mit "Vorlagenname" an und bestimmen Sie den Variablennamen des Objekts am Überbrückungsziel mit "Kontextobjektname".
Abgesehen von ersteren muss ich mich für letztere entscheiden
{% for question in latest_question_list %}
Wo ich so schrieb
{% for question in object_list %}
Wenn Sie es nicht schreiben, wird es nicht funktionieren. Es versteht sich von selbst, welches auf den ersten Blick leichter zu verstehen ist. Übrigens können Sie mithilfe eines Mechanismus namens "Context Processor" eine Vorlagenvariable in einer separaten Datei definieren und importieren, sodass Sie sie hier nicht einzeln angeben müssen. Es kann auch wie eine globale Variable in einer Vorlage verwendet werden. Referenz: Einführung von Google Analytics in Django
DetailView
DetailView
ist eine klassenbasierte Ansicht, die für einzelne Detailseiten verwendet werden kann.
Die Ansicht, die Sie für Seiten wie "polls / 1 / detail" verwenden möchten.
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
Sie können sehen, dass Sie das Modell und die Vorlage angeben. Darüber hinaus müssen Sie in "urls.py" "pk" oder "slug" angeben, diesmal jedoch "pk".
Dies sind die beiden klassenbasierten Ansichten, die in diesem Lernprogramm verwendet werden, aber es gibt mehrere andere. Dieses Mal werfen wir einen kurzen Blick auf ihre Ansichten.
generic.base.View
Dies ist die Hauptklasse der klassenbasierten Ansicht. Jede Klassenbasis erbt dies, und indem wir es erben, verwenden wir die Klassenbasis.
Anwendungsbeispiel
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('Hello, World!')
Beide können für Formulare verwendet werden, was zu Ansichten mit Aktualisierungsverarbeitung führt. Die Rolle von "FormView" besteht darin, das Formular anzuzeigen, wenn es die "HTTP-Methode GET" empfängt, dh das Formular anzuzeigen, wenn die in "Pfad" festgelegte "URL" getroffen wird. Wenn Sie dann die HTTP-Methode POST erhalten, können Sie den Prozess basierend auf der vom Formular empfangenen Anforderung ausführen. Es scheint für Formulare verwendet zu werden, die eine Umleitungsverarbeitung ohne zusätzliche Datenbankverarbeitung durchführen. Beispielsweise verfügt das als Beispiel angegebene Anmeldeformular über eine separate Ansicht, die als Authentifizierungsansicht "LoginView" bezeichnet wird. Daher wird anscheinend häufig die letztere verwendet, die später beschrieben wird.
Anwendungsbeispiel
from django import forms
class ContactForm(forms.Form):
name = forms.CharField()
message = forms.CharField(widget=forms.Textarea)
def send_email(self):
# send email using the self.cleaned_data dictionary
pass
Für "CreateView" wird der "Einfügen" -Prozess für das angegebene Modell basierend auf der "Anforderung" ausgeführt, die vom Formular empfangen wird, wenn die "HTTP-Methode POST" empfangen wird. Mit anderen Worten, es kann für Formulare verwendet werden, die neue Datensätze (Daten) hinzufügen.
Anwendungsbeispiel
from django.views.generic.edit import CreateView
from myapp.models import Author
class AuthorCreate(CreateView):
model = Author
fields = ['name']
UpdateView
ist keine Ergänzung, sondern eine Ansicht, die für Formulare verwendet wird, bei denen vorhandene Datensätze aktualisiert werden.
Anwendungsbeispiel
from django.views.generic.edit import UpdateView
from myapp.models import Author
class AuthorUpdate(UpdateView):
model = Author
fields = ['name']
template_name_suffix = '_update_form'
Jetzt können Sie sehen, dass die Variablen "Felder" in "UpdateView" und "CreateView" definiert sind. Dies ist ein Element, das festgelegt werden muss, wenn beide Ansichten verwendet werden. Die vom Formular eingegebenen Daten werden mit Ausnahme der angegebenen Felder ignoriert. Mit anderen Worten, im obigen Beispiel wird unabhängig davon, wie viele Eingabeelemente im Formular beispielsweise "Adresse" oder "Tel" entsprechen, nur das Feld "Name" hinzugefügt / aktualisiert. Diese Spezifikation kann in einer Liste oder einem Taple festgelegt werden, sodass Sie mehrere angeben können.
Nachdem wir die Rolle jeder Klassenbasis kurz identifiziert und ihre Definition bestätigt haben, besteht der nächste Schritt darin, "urls.py" so zu ändern, dass die generische Ansicht verwendet werden kann.
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
Zuvor mussten Sie "pk" angeben, um "DetailView" zu verwenden. Stellen Sie sicher, dass "<int: question_id>" jetzt "<int: pk>" ist.
Ändern Sie abschließend views.py
wie am Anfang dieses Elements beschrieben.
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
from .models import Question, Choice
# Create your views here.
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
#Zugriff auf POST-Daten. Dieses Mal wird die ID der Option, die über das Optionsfeld im Formular ausgewählt wurde, als Zeichenfolge zurückgegeben und der Variablen zugewiesen.
selected_choice = question.choice_set.get(pk=request.POST['choice'])
#Geben Sie den Schlüsselfehler in der Ausnahmespezifikation an. Ausnahmebehandlung, wenn keine Wahl besteht.
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', { 'question':question, 'error_message':"You didn't select a choice.",})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
#Weiterleitungsverarbeitung in Django. umkehren()In URLs.Rufen Sie die URL über den in py festgelegten benannten Pfad auf. Sie können eine bestimmte Seite angeben, indem Sie das Argument angeben.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Ich hatte das Gefühl, dass Verständnis hier unvermeidlich ist, wenn es um Django geht.
Einführung von Google Analytics in Django Einführung in klassenbasierte generische Ansichten in Django und Beispielverwendung Sammeln der allgemeinen Klassenansichten von Django und Erwähnen der Implementierung
Recommended Posts