Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps mit Python ~ Django Tutorial 4 ~

Einführung

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.

Über das Formular


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

Generische Ansicht (klassenbasierte Ansicht)

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!')

generic.edit.FormView und generic.edit.CreateView und generic.edit.UpdateView

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.

Ändern Sie die URLconf

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.

views.py-Einstellungen

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

Schließlich

Ich hatte das Gefühl, dass Verständnis hier unvermeidlich ist, wenn es um Django geht.

Referenz

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

Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 5 ~
Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps mit Python ~ Django Tutorial 4 ~
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 1, 2, 3 ~
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 6 ~
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 7 ~
Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps in Python ~ Indexseite ~
Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps in Python ~ Denken Sie ein wenig über die Definition von Anforderungen nach ~
Lernverlauf für die Teilnahme an der Entwicklung von Teamanwendungen mit Python ~ Ergänzung der Grundelemente und Aufbau der jupyterLab-Umgebung ~
Lernverlauf zur Teilnahme an der Entwicklung von Teamanwendungen mit Python ~ Build Docker / Django / Nginx / MariaDB-Umgebung ~
Lernverlauf zur Teilnahme an der Entwicklung von Teamanwendungen mit Python ~ Nach Abschluss von "Einführung in Python 3" des Paiza-Lernens ~
Python Django Tutorial (5)
Python Django Tutorial (2)
Python Django Tutorial (8)
Python Django Tutorial (6)
Python Django Tutorial (7)
Python Django Tutorial (1)
Python Django Tutorial Tutorial
Python Django Tutorial (3)
Python Django Tutorial (4)
Boost.NumPy Tutorial zum Erweitern von Python in C ++ (Übung)
[Implementierung zum Lernen] Implementieren Sie Stratified Sampling in Python (1)
Lernnotizen für die Migrationsfunktion im Django-Framework (2)
Zusammenfassung des Python Django-Tutorials
Erstellen Sie mit Python eine interaktive Umgebung für maschinelles Lernen
Verzeichnisstruktur für die testgetriebene Entwicklung mit pytest in python
App-Entwicklung zum Twittern in Python aus Visual Studio 2017
Lernnotizen für die Migrationsfunktion im Django-Framework (3)
Lernnotizen für die Migrationsfunktion im Django-Framework (1)
Tiefes Lernen mit Python Kapitel 2 (Material für runde Vorlesung)
Framework-Entwicklung mit Python
Entwicklungsumgebung in Python
Entwicklung des AWS SDK für Python (Boto3) in Visual Studio 2017
Slackbot-Entwicklung in Python
Tutorial für die testgetriebene Entwicklung (TDD) mit Flask-2-Dekorateuren
Erstellen einer Entwicklungsumgebung für Android-Apps - Erstellen von Android-Apps mit Python
Tutorial für die testgetriebene Entwicklung (TDD) mit Flask-1 Test Client Edition
Lernablauf für Python-Anfänger
Python-Lernplan für KI-Lernen
Techniken zum Sortieren in Python
Python-Entwicklung mit Visual Studio 2017
Qt für Python App Selbstaktualisierung
Python Django Tutorial Cheet Sheet
Checkios Empfehlung zum Erlernen von Python
[Zum Organisieren] Python-Entwicklungsumgebung
Python-Entwicklung mit Visual Studio
Über "für _ in range ():" von Python
Wie wäre es mit Anaconda zum Erstellen einer maschinellen Lernumgebung mit Python?
Ändern Sie automatisch die Größe von Screenshots für den App Store für jeden Bildschirm in Python
Gehirnwellenanalyse mit Python: Python MNE-Tutorial
Implementieren Sie das Stacking-Lernen in Python [Kaggle]
Überprüfen Sie Python auf Speicherlecks
Suchen Sie mit Python nach externen Befehlen
Web-Lehrmaterialien zum Erlernen von Python
[Für Anfänger] Django -Entwicklungsumgebung Bau-
In Python implementierte Widrow-Hoff-Lernregeln
Optionen für die Python-Entwicklungsumgebung für Mai 2020
<Für Anfänger> Python-Bibliothek <Für maschinelles Lernen>
Emacs-Einstellungen für die Python-Entwicklungsumgebung
Python: Vorverarbeitung beim maschinellen Lernen: Übersicht