[PYTHON] Résumé du didacticiel Django pour les débutants par les débutants ④ (Vue générique)

introduction

Cet article est une série qui fait progresser le didacticiel officiel de Django. Cette fois, nous allons procéder avec le 4ème article "Création de votre première application Django, partie 4".

Résumé du tutoriel Django pour les débutants par les débutants ① (création de projet ~) Résumé du tutoriel Django pour les débutants par les débutants ② (Modèle, Admin) Résumé du tutoriel Django pour les débutants par les débutants ③ (Afficher) Résumé du tutoriel Django pour les débutants par les débutants ④ (Vue générique) Résumé du tutoriel Django pour les débutants par les débutants ⑤ (test) Résumé du tutoriel Django pour les débutants par les débutants ⑥ (fichier statique) Résumé des tutoriels Django pour les débutants par les débutants ⑦ (Customize Admin)

Création de votre première application Django, partie 4

https://docs.djangoproject.com/ja/3.0/intro/tutorial04/

Write a minimal form Placez le formulaire de vote dans le detail.html créé dans l'article précédent.

polls/templates/polls/detail.html


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

forloop.counter est une valeur qui indique combien de fois la boucle de la balise for a été exécutée. Si vous regardez le contenu, vous pouvez voir que tous les choix liés à Question sont affichés sous forme de choix de bouton radio dans l'instruction for.

Vous devez insérer {% csrf_token%} lors de la création d'un formulaire POST pour les mesures CSRF.

Puis éditez polls / views.py pour que le vote fonctionne bien.

polls/views.py


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

Par request.POST ['choice'], la valeur POSTed par le nom de'choice 'dans le formulaire ci-dessus est lue comme selected_choice.

Une KeyError est lancée lorsque request.POST ['choice'] n'existe pas (c'est-à-dire si l'utilisateur ne sélectionne rien). Dans ce cas, le formulaire sera à nouveau rendu avec un message d'erreur.

Lorsque le processus est terminé normalement, il redirige vers les résultats. (La redirection doit être appliquée lorsque le traitement tel que POST est terminé normalement (quel que soit Django))

Vous pouvez empêcher le revêtement dur URL avec la fonction reverse. L'utilisation est similaire à la spécification d'URL utilisée dans ʻindex.html`.

Maintenant, ajoutez la vue des résultats à polls / views.py.

polls/views.py


from django.shortcuts import get_object_or_404, render


def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': question})

Le contenu est presque le même que la vue du «détail».

Créons également un modèle.

polls/templates/polls/results.html


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

Avez-vous remarqué qu'il y a un problème jusqu'à présent?

Dans le flux de traitement actuel, récupérez d'abord selected_choice de DB, calculez une nouvelle valeur à partir de ses votes et enregistrez-la dans DB.

Même si la valeur des voix était à l'origine de 42, si MM. A et B votent en même temps, la place qui devrait initialement être de 44 devient 43.

Il semble qu'un tel problème s'appelle un "problème de conflit", et l'article suivant sera utile pour l'explication de F () pour le résoudre. Tous les enregistrements jusqu'à ce qu'oncle Java puisse utiliser Python (n ° 16)

Utilisez une vue générique: moins de code, c'est bien

Django a un raccourci appelé Vue générale (vue générique)

Récupère les données de la base de données en fonction des paramètres passés via l'URL, charge le modèle et renvoie le modèle rendu. Ceci est si courant que Django propose un raccourci appelé la vue générique. Une vue générique est une abstraction de modèles courants qui vous permet d'écrire une application sans même écrire de code Python.

... Apparemment ...

Modifier URLconf

Modifiez polls / urls.py comme suit

polls/urls.py


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

La différence est que views.IndexView.as_view () etc. est passé à la vue spécifiée par path. De plus, «question_id» a été renommé en «pk». (La raison sera décrite plus tard)

Créez la classe ʻIndexView` etc. dans la vue.

polls/views.py


from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic

from .models import Choice, Question


class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        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):
    ... # same as above, no changes needed.

«ListView» et «DetailView» sont utilisés. Le question_id a été renommé en pk car il est spécifié comme tel dans DetailView.

Par défaut, la vue générique DetailView utilise un modèle nommé <nom de l'application> / <nom du modèle> _detail.html, mais vous pouvez changer le modèle utilisé en spécifiant l'attribut nom_modèle. (Idem pour ListView)

Recommended Posts

Résumé du didacticiel Django pour les débutants par les débutants ④ (Vue générique)
Résumé du tutoriel Django pour les débutants par les débutants ③ (Afficher)
Résumé du tutoriel Django pour les débutants par les débutants ⑤ (test)
Résumé du tutoriel Django pour les débutants par les débutants ⑦ (Personnaliser l'administrateur)
Résumé du tutoriel Django pour les débutants par les débutants ⑥ (fichier statique)
Résumé du tutoriel Django pour les débutants par les débutants ② (Modèle, Admin)
Résumé du tutoriel Django pour les débutants par les débutants ① (création de projet ~)
[Explication pour les débutants] Tutoriel TensorFlow MNIST (pour les débutants)
Résumé de l'apprentissage automatique par les débutants de Python
[Pour les débutants] Django -Construction d'environnement de développement-
Qu'est-ce que le grattage? [Résumé pour les débutants]
Tutoriel TensorFlow MNIST pour les débutants en ML
Résumé du didacticiel Django Girls Première moitié
Lien récapitulatif des bases de Pandas pour les débutants
[Déprécié] Tutoriel pour débutant Chainer v1.24.0
Tutoriel TensorFlow -MNIST pour les débutants en ML
[Explication pour les débutants] Tutoriel TensorFlow Deep MNIST
[Résumé des commandes Linux] Liste des commandes [À voir absolument pour les débutants]
Résumé de Django
Ajax dans Django (en utilisant la vue de classe générique)
Un manuel pour les débutants réalisé par des débutants Python
Une introduction à la programmation orientée objet pour les débutants par les débutants
À propos des fonctions d'ordre supérieur de Nim pour les débutants Nim écrites par les débutants Nim
Réalisation du didacticiel TensorFlow MNIST pour débutants en ML
Tutoriel Python Django (5)
Tutoriel Python Django (2)
Résumé du didacticiel Python
Prise en charge de l'internationalisation avec Django 1.9
mémo du didacticiel django
Tutoriel Python Django (8)
Tutoriel Python Django (6)
Démarrer le didacticiel Django 1
Vue basée sur les classes Django
Résumé du filtre Django
Tutoriel Python Django (7)
Tutoriel Python Django (1)
Tutoriel du didacticiel Python Django
Tutoriel Python Django (3)
Tutoriel Python Django (4)
[Français] Tutoriel officiel NumPy "NumPy: les bases absolues pour les débutants"
J'ai essayé le tutoriel MNIST de tensorflow pour les débutants.
Résumé des méthodes de prétraitement pour les débutants en Python (trame de données Pandas)
Comment utiliser le bootstrap dans la vue de classe générique Django
Remarque DJango: depuis le début (en utilisant une vue générique)
[Linux] Principes de base de la configuration des autorisations par chmod pour les débutants
Comment télécharger des fichiers dans la vue de classe générique Django
[Pour les débutants] Django Commandes fréquemment utilisées et collection de références