[PYTHON] Lancez-vous avec Django! ~ Tutoriel ④ ~

Aperçu

Ceci est une continuation de Dernière fois. Cette fois, je me concentrerai sur le traitement des formulaires et la réduction du code par Django.

Création de formulaire

Mettons à jour polls / detail.html créé dans le didacticiel Dernière fois pour inclure l'élément HTML \

.

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>

Les points sont les suivants.

--csrf_token est une contre-mesure de requête intersite fournie par Django. --forloop.counter représente le décompte dans la boucle for de Django. ――Après cela, sur la voie royale du développement Web, lorsque vous soumettez, le nom et les valeurs de valeur sélectionnés sont envoyés à la destination d'action spécifiée.

Ensuite, modifions la destination sondages / vote```. Ce sera une modification de vue.

polls/views.py


from django.shortcuts import render, get_object_or_404
from .models import Question, Choice  #Modèle de choix ajouté
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse  #Ajouter l'inverse


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)
    context = {
        'question': question
    }
    return render(request, 'polls/detail.html', context)


def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

#ViewAction modifié cette fois
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):
        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 HttpResponseRedirect(
            reverse('polls:results', args=(question.id))
        )

Action de vote fixe. J'expliquerai les parties qui ne sont pas apparues jusqu'à présent dans l'explication.

request.POST

Nous avons toujours spécifié request comme premier argument d'une action. Il est enfin temps de l'utiliser ici.

C'est un objet de type dictionnaire qui peut accéder aux données POST envoyées par request.POST. Dans ce cas, le choix associé à l'objet question est choisi_set.get, et pk est spécifié comme filtre get.

À ce moment-là, si vous faites request.POST ['choice'], vous pouvez accéder au choix des données POST. (le choix est le choix de l'attribut de nom)

De même, request.GET existe également, mais cette fois, nous envoyons des données POST avec method = POST, nous les obtiendrons donc par POST.

S'il n'y a pas de choix POST, KeyError sera levé. Le code ci-dessus vérifie KeyError et réaffiche le formulaire de question avec un message d'erreur s'il n'y a pas de choix.

Après un traitement des données POST réussi

Cela ne se limite pas à Django, mais comme meilleure pratique pour le développement Web, après un traitement réussi des données POST, redirigez vers la page cible.

Dans ce cas, j'utilise HttpResponseRedirect fourni par Django pour effectuer la transition vers le résultat.

Dans HttpResponseRedirect, utilisez la fonction inverse.

Le premier argument de la fonction inverse spécifie le modèle URLconf. Le deuxième argument spécifie les paramètres requis pour la transition.

Créer une page de résultats

Enfin, créez une page de résultats.

polls/views/py


from django.shortcuts import render, get_object_or_404
from .models import Question, Choice
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse


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)
    context = {
        'question': question
    }
    return render(request, 'polls/detail.html', context)

#Vue ajoutée cette fois
def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    context = {
        'question': question
    }
    return render(request, 'polls/results.html', context)


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):
        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 HttpResponseRedirect(
            reverse('polls:results', args=(question.id,))
        )

Tout d'abord, ajoutez une vue. Le contenu est très simple.

Ensuite, créez 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}}&nbsp;--&nbsp;{{choice.votes}}&nbsp;vote{{choice.votes|pluralize}}</li>
    {% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>
<br />
<a href="{% url 'polls:index' %}">To TOP</a>

Le résultat du vote est affiché en faisant tourner la boucle du nombre de choix.

Ceci complète les fonctions de l'application.

Utiliser une vue générique

L'un des concepts de Python est que "moins de code, c'est bien". Django, bien sûr, adopte cette idée.

Faisons une vue plus simple en modifiant légèrement les vues que nous avons créées jusqu'à présent.

Le point de vue que j'ai développé jusqu'à présent a été la méthode de développement Web.

Récupérez les données de la base de données en fonction des paramètres transmis via l'URL. ↓ Chargez le modèle. ↓ Rendez et renvoyez le modèle.

Comme le processus ci-dessus est extrêmement général, il existe un raccourci sous forme de vue générique dans Django.

Une vue générique est une abstraction de modèles courants qui vous permet d'écrire votre application sans même écrire de code Python.

Faire d'une vue générique une vue générique est une étape ci-dessous.

① Convertissez URLconf. ② Supprimez l'ancienne vue inutile. ③ Réglez la vue générale de Django sur la nouvelle vue.

Commencez par convertir les paramètres URLconf.

polls/urls.py


from django.conf.urls import url

from . import views

app_name = 'polls'

urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),  #Correction de passer par la classe IndexView
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),  #Modifié pour passer par la classe DetailView
    url(
        r'^(?P<pk>[0-9]+)/results/$',
        views.ResultsView.as_view(),
        name='results'
    ),   #Modifié pour passer par la classe DetailView
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

Le nom du modèle correspondant aux deuxième et troisième expressions régulières a été remplacé par .

Ensuite, modifiez la vue.

polls/views.py


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


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:
        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 HttpResponseRedirect(
            reverse('polls:results', args=(question.id,))
        )

Ici, la vue d'affichage du modèle est classée. Le parent de la classe hérite de la classe enfant générique nouvellement importée.

generic.DetailView

Voir la page de détails.

Chaque vue doit savoir pour quel modèle elle fonctionne. Ceci est défini comme modèle proty.

En outre, la vue générique DetailView est censée capturer et transmettre la clé primaire à partir de l'URL portant le nom ** pk **. C'est pourquoi je l'ai modifié plus tôt en pk dans URLconf.

Par défaut, la vue générique DetailView fait référence au modèle / _detail.html```.

Cette fois, il s'agit d'un nom de modèle unique, vous devez donc indiquer explicitement le modèle dans la propriété template_name. (Template_name n'est pas obligatoire si vous créez selon les conventions de dénomination.)

De plus, la variable de contexte utilise le nom du modèle.

generic.ListView

La convention de dénomination pour le modèle par défaut de ListView est `` / _list.html ''.

Puisqu'il s'agit de notre propre modèle, nous utiliserons la propriété template_name.

De plus, la liste des données acquises par défaut est stockée dans la variable de contexte `` _list```.

Cette fois, toute l'application utilise une variable de contexte appelée `` last_question_list ''.

Par conséquent, le nom de la variable de contexte est remplacé par la propriété context_objext_name```.

Enfin, définissez la méthode `` get_queryset () '' qui stocke la valeur dans la variable de contexte.

Résumé

Cette fois,

--Création de formulaires --Utilisation de la vue à usage général

J'ai expliqué.

La création de formulaires n'était pas différente des frameworks dans d'autres langues, mais les vues génériques étaient un peu bizarres.

Si je me souviens bien, j'ai pu sélectionner une vue à partir de l'URL, sélectionner un modèle dans la vue, le rendre et le renvoyer sous forme de HttpResponse avec presque aucun code écrit dans le didacticiel.

Vous devrez vous y habituer, mais cela vaut la peine de s'en souvenir. (En fin de compte, React fera une table, donc cela n'a peut-être pas de sens ...)

La prochaine fois, j'aimerais présenter un test automatisé à l'aide de l'application de vote que j'ai créée.

GitHub

séries

Recommended Posts

Lancez-vous avec Django! ~ Tutoriel ⑤ ~
Lancez-vous avec Django! ~ Tutoriel ④ ~
Lancez-vous avec Django! ~ Tutoriel ⑥ ~
Comment démarrer avec Django
Django 1.11 a démarré avec Python3.6
Premiers pas avec Django 1
Démarrez avec MicroPython
Démarrez avec Mezzanine
Premiers pas avec Django 2
Le moyen le plus simple de démarrer avec Django
Commencez avec influxDB + Grafana
Premiers pas avec Python Django (1)
Premiers pas avec Python Django (4)
Premiers pas avec Python Django (3)
Introduction à Python Django (6)
Commencez avec Python! ~ ② Grammaire ~
Premiers pas avec Django avec PyCharm
Premiers pas avec Python Django (5)
Commencez avec Python! ~ ① Construction de l'environnement ~
Lien pour commencer avec python
Premiers pas avec MicroPython (sur macOS)
Comment démarrer avec Scrapy
Comment démarrer avec Python
Démarrez avec l'apprentissage automatique avec SageMaker
Démarrez avec Python avec Blender
Premiers pas avec le framework Python Django sur Mac OS X
Tutoriel Python Django (5)
Tutoriel Python Django (2)
CRUD GET avec Nuxt & Django REST Framework ②
Internationalisation avec Django
mémo du didacticiel django
J'ai essayé de résumer brièvement la procédure de démarrage du développement de Django
Tutoriel Python Django (8)
CRUD GET avec Nuxt & Django REST Framework ①
Tutoriel Python Django (6)
Démarrer le didacticiel Django 1
Premiers pas avec l'outil de documentation Sphinx
Commençons avec TopCoder en Python (version 2020)
CRUD avec Django
Tutoriel Python Django (7)
Tutoriel Python Django (1)
Tutoriel du didacticiel Python Django
Comment les débutants en Python commencent avec Progete
Tutoriel Python Django (3)
[Blender x Python] Commençons avec Blender Python !!
Tutoriel Python Django (4)
Django Getting Started Part 2 avec eclipse Plugin (PyDev)
Zubu amateur veut démarrer Python
[Cloud102] # 1 Premiers pas avec Python (première partie des premiers pas de Python)
Authentifier Google avec Django
Télécharger des fichiers avec Django
Résumé du développement avec Django
Démarrer Jupyter Notebook
Résumé du didacticiel Python Django
Sortie PDF avec Django
Premiers pas avec Android!
Sortie Markdown avec Django
1.1 Premiers pas avec Python