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.
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.
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.
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}} -- {{choice.votes}} 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.
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.
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.
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
Recommended Posts