Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 4 ~

introduction

À partir de Dernière fois, nous allons continuer avec le tutoriel Django. Cette fois, je parlerai de la vue basée sur les classes, qui est un point important lors de l'utilisation de Django.

À propos du formulaire


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


Par exemple, supposons que vous souhaitiez créer un formulaire comme celui-ci. C'est un formulaire qui prépare une réponse avec un bouton radio pour une certaine question, la vérifie et l'envoie par POST. {{forloop.counter}} est le nombre de boucles pour {% pour le choix dans question.choice_set.all%}. La notation réelle serait, par exemple, <input type =" radio "name =" choice "id =" choice1 "value =" 1 ">. Jetons un coup d'œil à la vue pour cela.

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

        #Le code ci-dessus provoque des problèmes de conflit, donc F(Nom de colonne)Utilisez la méthode.
        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,)))


La différence par rapport à la dernière fois est que les objets HttpResposeRedirect et reverse ont été importés. La première est une méthode de redirection, et la seconde méthode reverse () est une méthode qui renvoie une URL et appelle l'URL à partir du chemin nommé défini dans urls.py. Par exemple, dans le cas ci-dessus L'URL / polls / results est renvoyée, mais vous pouvez renvoyer l'URL / polls / 1 / results en spécifiant question.id comme argument.

Si vous comprenez le contenu de la fonction de vote elle-même jusqu'à la dernière fois, il n'est pas si difficile de comprendre ce que vous faites. Tout d'abord, affectez une instance à la variable. Puisqu'il s'agit d'une méthode get_object_or_404, il s'agit d'une instance des données de clé primaire correspondantes du modèle Question. Nous le traiterons comme une exception avec le modèle try-catch-else. Tout d'abord, sur la base des données POST envoyées depuis le formulaire, la méthode get () est utilisée pour obtenir les données de la base de données. request.POST vous permet d'accéder aux données envoyées avec la clé spécifiée. Par exemple, dans ce cas de request.POST ['choice'], cela signifie accéder aux données dont l'attribut name est choice.


<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">

Ce sera cette partie.

Donc, cette fois, c'est un formulaire avec un bouton radio, donc il y a des choix dans la boucle for, mais comme il n'y a qu'une seule donnée à envoyer, la valeur de la valeur du choix est retirée et transformée en pk. Devenir. Au fait, s'il y a plusieurs mêmes attributs name tels que des cases à cocher, veuillez utiliser getlist () ʻau lieu de get (). Parole silencieuse, par exemple, question.choice_set.get (pk = request.POST ['choice'])devientquestion.choice_set.get (pk = 1), c'est-à-dire que les données avec la clé primaire 1 sont choice Il sera recherché dans le modèle et assigné à la variable en tant qu'instance. S'il peut être obtenu en toute sécurité, il passera à ʻelse, s'il ne peut pas être obtenu, il sera traité comme une exception de KeyError, et le message d'erreur sera retourné par la méthode render () et renvoyé à l'écran de formulaire. Le processus de ʻelse` consiste à augmenter le décompte du nombre de votes, à le mettre à jour dans la base de données et à rediriger vers l'écran des résultats du vote. Créons maintenant un modèle pour les résultats du vote.


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


La partie de vote {{choice.votes | pluralize}} est l'expression qui indique que si la valeur à gauche de pluiralize est une forme plurielle, un suffixe indiquant la forme plurielle est renvoyé. Par exemple, dans ce cas, si «choice.votes» vaut 2, alors «vote» devient «votes».

Vue générique (vue basée sur les classes)

Eh bien, j'ai écrit plusieurs vues (contrôleurs) jusqu'à présent, mais Django a une vue intégrée dite à usage général appelée vue basée sur les classes. view a le rôle de relier les données et ʻURL` au modèle, mais même si cela est arrivé si loin

-Créer et afficher une liste avec filter () -Obtenir les données de la base de données et les refléter dans le modèle · Afficher l’une des nombreuses pages telles que «sondages / 1 / résultats»

Je pense qu'un tel processus est sorti plusieurs fois et j'ai écrit «view» à chaque fois. Une vue à usage général est un système qui définit à l'avance les valeurs par défaut appropriées en fonction du modèle et du formulaire afin que vous n'ayez pas à écrire un tel traitement plusieurs fois. Au fait, comme vous pouvez le voir du fait qu'il est basé sur une classe, la vue générale dans Django est fournie par la classe. Il semble qu'il y ait aussi une base de fonctions. Jetons un œil à la précédente vue.


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

Ensuite, voici la nouvelle vue à écrire


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:
		#Accédez aux données POST. Cette fois, l'ID de l'option sélectionnée par le bouton radio du formulaire est renvoyé sous forme de chaîne de caractères et affecté à la variable.
		selected_choice = question.choice_set.get(pk=request.POST['choice'])
	#Spécifiez l'erreur de clé dans la spécification d'exception. Traitement des exceptions s'il n'y a pas le choix.
	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()
		#Rediriger le traitement dans Django. inverser()Dans les URL.Appelez l'URL à partir du chemin nommé défini dans py. Vous pouvez spécifier une page spécifique en spécifiant l'argument.
		return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

Vous pouvez voir que c'est tout à fait différent. Tout d'abord, importez l'objet générique depuis le module django.views. Il peut également être importé et utilisé pour chaque vue basée sur une classe, telle que from django.views.generic import ListView. Dans ce cas, l'argument serait «ListView» au lieu de «generic.ListView». Et comme mentionné ci-dessus, puisqu'il s'agit d'une vue basée sur les classes, nous réécrirons ce qui était précédemment écrit en tant que fonction dans une classe et hériterons et utiliserons chaque vue basée sur les classes. Par exemple, cela ressemble à class IndexView (generic.ListView):. Puisqu'il hérite, spécifiez la vue à usage général que vous souhaitez utiliser comme argument. Bien entendu, l'héritage peut également être remplacé. Regardons chacun d'eux.

Listview

Listview est une vue pour afficher une liste d'objets. En d'autres termes, il peut être utilisé lors de la création d'une page de liste.


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]

Lorsque vous l'utilisez réellement, il sera écrit comme ci-dessus. Normalement, il est essentiel de spécifier le modèle lors de l'utilisation de la vue basée sur les classes, mais vous pouvez également spécifier la méthode de queryset (). Par exemple, dans ce qui précède, au lieu d'afficher simplement la liste des modèles, nous voulons afficher la liste par incréments de 5, donc nous spécifions avec query set () au lieu de spécifier le modèle. Après cela, spécifiez le modèle de la destination de pontage avec template_name, et décidez du nom de variable de l'objet à la destination de pontage avec context_object_name. Hormis le premier, je dois décider du second

{% for question in latest_question_list %}

Où j'écrivais comme ça

{% for question in object_list %}

Si vous ne l'écrivez pas, cela ne fonctionnera pas. Il va sans dire lequel est le plus facile à comprendre à première vue. D'ailleurs, en utilisant un mécanisme appelé «Processeur de contexte», vous pouvez définir une variable de modèle dans un fichier séparé et l'importer afin que vous n'ayez pas à la spécifier individuellement ici. Il peut également être utilisé comme une variable globale dans un modèle. Référence: Présentation de Google Analytics à Django

DetailView

DetailView est une vue basée sur les classes qui peut être utilisée pour des pages de détails individuelles. La vue que vous souhaitez utiliser pour des pages telles que sondages / 1 / détail.


class DetailView(generic.DetailView):

	model = Question
	template_name = 'polls/detail.html'

Vous pouvez voir que vous spécifiez le modèle et le modèle. En plus de cela, vous devez spécifier pk ou slug dans ʻurls.py, mais cette fois, spécifiez pk` après cela.

Ce sont les deux vues basées sur les classes utilisées dans ce didacticiel, mais il y en a plusieurs autres, donc cette fois, nous allons simplement jeter un coup d'œil à ce qu'elles ont.

generic.base.View

Il s'agit de la classe principale de la vue basée sur les classes. Chaque base de classe en hérite et en héritant, nous utilisons la base de classe.

Exemple d'utilisation



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 et generic.edit.CreateView et generic.edit.UpdateView

Les deux peuvent être utilisés pour les formulaires, ce qui donne des vues avec un traitement de mise à jour. Le rôle de «FormView» est d'afficher le formulaire lorsqu'il reçoit la «méthode HTTP GET», c'est-à-dire d'afficher le formulaire lorsque «l'URL» définie dans «path» est atteinte. Ensuite, lorsque vous recevez la méthode HTTP POST, vous pouvez exécuter le processus en fonction de la demande reçue du formulaire. Il semble être utilisé pour les formulaires qui effectuent un traitement de redirection sans traitement de base de données supplémentaire, Par exemple, le formulaire de connexion donné à titre d'exemple a une vue séparée appelée la vue d'authentification appelée LoginView, il semble donc que cette dernière, qui sera décrite plus loin, est souvent utilisée.

Exemple d'utilisation



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

Pour CreateView, le processus insert est exécuté pour le modèle spécifié en fonction de la demande reçue du formulaire lorsque la méthode HTTP POST est reçue. En d'autres termes, il peut être utilisé pour les formulaires qui ajoutent de nouveaux enregistrements (données).

Exemple d'utilisation



from django.views.generic.edit import CreateView
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

ʻUpdateView` n'est pas un ajout, mais une vue utilisée pour les formulaires qui impliquent la mise à jour d'enregistrements existants.

Exemple d'utilisation



from django.views.generic.edit import UpdateView
from myapp.models import Author

class AuthorUpdate(UpdateView):
    model = Author
    fields = ['name']
    template_name_suffix = '_update_form'

Vous pouvez maintenant voir que les variables fields sont définies dans ʻUpdateView et CreateView`. Il s'agit d'un élément qui doit être défini lors de l'utilisation des deux vues, et cela signifie que les données saisies à partir du formulaire sont ignorées sauf pour les champs spécifiés. En d'autres termes, dans l'exemple ci-dessus, quel que soit le nombre d'éléments d'entrée dans le formulaire correspondant, par exemple, «adresse» ou «Tel», seul le champ «nom» sera ajouté / mis à jour. Cette spécification peut être définie dans une liste ou une taple, vous pouvez donc en spécifier plusieurs.

Modifier URLconf

Maintenant que nous avons brièvement identifié le rôle de chaque base de classe et confirmé comment le définir, l'étape suivante est de modifier ʻurls.py` pour qu'il puisse utiliser la vue générique.


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

]

Auparavant, vous deviez spécifier pk pour utiliser DetailView. Assurez-vous que <int: question_id> est maintenant <int: pk>.

paramètres views.py

Enfin, modifiez views.py comme décrit au début de cet élément.


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:
		#Accédez aux données POST. Cette fois, l'ID de l'option sélectionnée par le bouton radio du formulaire est renvoyé sous forme de chaîne de caractères et affecté à la variable.
		selected_choice = question.choice_set.get(pk=request.POST['choice'])
	#Spécifiez l'erreur de clé dans la spécification d'exception. Traitement des exceptions s'il n'y a pas le choix.
	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()
		#Rediriger le traitement dans Django. inverser()Dans les URL.Appelez l'URL à partir du chemin nommé défini dans py. Vous pouvez spécifier une page spécifique en spécifiant l'argument.
		return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

finalement

J'ai senti que la compréhension ici est inévitable lorsque l'on traite avec Django.

référence

Présentation de Google Analytics à Django Introduction à la vue générique basée sur les classes dans Django et exemple d'utilisation Collecte des vues de classe génériques de Django et mention de l'implémentation

Recommended Posts

Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 5 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 4 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 1, 2, 3 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 6 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe en Python ~ Tutoriel Django 7 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe en Python ~ Page d'index ~
Historique d'apprentissage pour participer au développement d'applications d'équipe en Python ~ Pensez un peu à la définition des exigences ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Supplément d'éléments de base et construction de l'environnement jupyterLab ~
Apprentissage de l'historique pour participer au développement d'applications d'équipe avec Python ~ Créer un environnement Docker / Django / Nginx / MariaDB ~
Apprentissage de l'histoire pour participer au développement d'applications en équipe avec Python ~ Après avoir terminé "Introduction à Python 3" de paiza learning ~
Tutoriel Python Django (5)
Tutoriel Python Django (2)
Tutoriel Python Django (8)
Tutoriel Python Django (6)
Tutoriel Python Django (7)
Tutoriel Python Django (1)
Tutoriel du didacticiel Python Django
Tutoriel Python Django (3)
Tutoriel Python Django (4)
Tutoriel Boost.NumPy pour l'extension de Python en C ++ (pratique)
[Implémentation pour l'apprentissage] Implémentation de l'échantillonnage stratifié en Python (1)
Notes d'apprentissage pour la fonction migrations dans le framework Django (2)
Résumé du didacticiel Python Django
Créez un environnement interactif pour l'apprentissage automatique avec Python
Structure de répertoire pour le développement piloté par les tests à l'aide de pytest en python
Développement d'applications pour tweeter en Python à partir de Visual Studio 2017
Notes d'apprentissage pour la fonction migrations dans le framework Django (3)
Notes d'apprentissage pour la fonction migrations dans le framework Django (1)
Apprendre en profondeur à l'expérience avec Python Chapitre 2 (Matériel pour une conférence ronde)
Développement de framework avec Python
Environnement de développement en Python
Développement du kit SDK AWS pour Python (Boto3) dans Visual Studio 2017
Développement Slackbot en Python
Tutoriel pour faire du développement piloté par les tests (TDD) avec Flask-2 Decorators
Création d'un environnement de développement pour les applications Android - Création d'applications Android avec Python
Tutoriel pour faire du développement piloté par les tests (TDD) avec Flask-1 Test Client Edition
Flux d'apprentissage pour les débutants en Python
Plan d'apprentissage Python pour l'apprentissage de l'IA
Techniques de tri en Python
Développement Python avec Visual Studio 2017
Mise à jour automatique de l'application Qt pour Python
Fiche technique du didacticiel Python Django
La recommandation de Checkio pour apprendre Python
[Pour organiser] Environnement de développement Python
Développement Python avec Visual Studio
À propos de "for _ in range ():" de python
Que diriez-vous d'Anaconda pour créer un environnement d'apprentissage automatique avec Python?
Redimensionner automatiquement les captures d'écran de l'App Store pour chaque écran en Python
Analyse des ondes cérébrales avec Python: tutoriel Python MNE
Mettre en œuvre l'apprentissage de l'empilement en Python [Kaggle]
Rechercher les fuites de mémoire dans Python
Rechercher des commandes externes avec python
Matériel pédagogique Web pour apprendre Python
[Pour les débutants] Django -Construction d'environnement de développement-
Règles d'apprentissage Widrow-Hoff implémentées en Python
Options d'environnement de développement Python pour mai 2020
<Pour les débutants> bibliothèque python <Pour l'apprentissage automatique>
Paramètres Emacs pour l'environnement de développement Python
Python: prétraitement dans l'apprentissage automatique: présentation