[PYTHON] Remarque DJango: depuis le début (traitement de formulaire)

Tutoriel 4. Nous sommes enfin entrés dans le tutoriel final. Nous terminerons une application de vote appelée sondages.

Modèle utilisant le formulaire

Décrivez le modèle de la page de détails comme suit.

detail.html ######

<h1>{{ poll.question }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="/polls/{{ poll.id }}/vote/" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}"
     value="{{ choice.id }}" />
    <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
{% endfor %}
<input type="submit" value="Voter" />
</form>

Il contient quelques mots que vous voyez pour la première fois.

Vous pouvez l'imaginer par son nom, mais c'est une valeur définie du côté views.py, vous n'avez donc pas à vous en souvenir séparément.

Un cliché qui signifie le nombre de fois où la boucle a été tournée. C'est facile à retenir car c'est juste le sens.

Mesures dites CSRF. Cela semble être le plus important. Si vous souhaitez envoyer une méthode POST à votre site, vous devez la considérer comme obligatoire. Alors, qu'est-ce que CSRF? Alors j'ai cherché sur Google. http://e-words.jp/w/CSRF.html Pour plus de commodité, views.py sera également modifié.

views.py ####

from django.template import RequestContext	#RequestContext semble être une sous-classe de Context
# ...
def detail(request, poll_id):
    pobject = get_object_or_404(Poll, pk=poll_id)	#pk est une abréviation de clé primaire. Mot reservé?
    return render_to_response('polls/detail.html', {'poll': pobject},
                               context_instance=RequestContext(request))	# context_Une nouvelle instance a été ajoutée. Peut-être des mots réservés

Mettez également en œuvre la partie vote.

from django.shortcuts import get_object_or_404, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.template import RequestContext
from polls.models import Choice, Poll
#...
def vote(request, poll_id):
    pobject = get_object_or_404(Poll, pk=poll_id)
    try:
        selected_choice = pobject.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render_to_response('polls/detail.html', {
            'poll': pobject,
            'error_message': "Choisissez d'abord l'option",
        }, context_instance=RequestContext(request))
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls.views.results', args=(pobject.id,)))

Voici quelques mots que je n'ai jamais vus auparavant, je vais donc les résumer.

Celui qui a reçu les données POSTÉES. Vous pouvez récupérer la valeur en fonction du nom en faisant request.POST ['name']. J'ai l'impression que dans certaines langues, il s'écrit $ _POST.

Une sous-classe de Context. Vous devez mettre l'objet HttpRequest dans le premier argument ici. Ici, la première requête d'argument du vote de la fonction de vue est entrée telle quelle (la HttpRequest accédée est probablement automatiquement affectée au premier argument de la fonction de vue).

Le nom (probablement fixe) à utiliser lors du retour de render_to_response avec un raccourci. Attribuez un objet HttpRequest.

render_to_response('for/your/template',{'name':value},context_instance)

Pensez-vous que vous spécifiez le modèle dans le premier argument, mettez les données dans le deuxième argument et transmettez les données au modèle dans la demande du troisième argument?

Mettez à jour la base de données définie. Ici, la valeur de selected_choice.votes (nom de données défini dans models.py) est incrémentée de un puis écrasée.

Je ne suis pas sûr de cela seul, donc si vous creusez un peu plus loin, Ce selected_choice semble faire référence aux données avec la valeur POSTed de'choice 'comme clé primaire du choice_set. Donc, ce choice_set est un ensemble de choix obtenu à partir de pobject (la façon d'écrire hoge_set semble être un cliché. Pour plus de détails, voir Tutoriel 1 dans tutorial01.html)). Lorsque j'examine le modèle, la valeur du bouton radio "choix" est "{{choice.id}}", et quel est cet identifiant?

python manage.py sql polls

Peut être confirmé à

"id" integer NOT NULL PRIMARY KEY

Les données ressemblent à ceci (l'identifiant semble être généré automatiquement même s'il n'est pas défini dans models.py). Bref, c'est comme quel nombre de choix.

En d'autres termes

# def vote….
        selected_choice.votes += 1
        selected_choice.save()

Dans la partie de, les données avec la valeur du choix sélectionné comme id sont ajoutées et enregistrées. Si vous cochez le modèle, cet identifiant sera la valeur du bouton radio tel quel, et par conséquent, les données de l'élément sélectionné par le bouton radio seront mises à jour.

Je suis surpris que cela fasse si longtemps, mais c'est probablement le flux du processus (veuillez me dire si c'est différent).

Dans les programmes précédents, c'était exclusivement HttpResponse, mais ici Redirect est attaché. Dans le premier argument inverse, le contenu est

’/polls/[id]/results/‘

Il est converti et renvoyé sous la forme. Spécifiez la destination de la redirection? args semble être l'argument à apporter à la destination de la redirection (peut-il être placé dans le poll_id de la fonction results?). Il n'y a qu'un seul contenu ici, mais n'oubliez pas d'ajouter une virgule! Il semble être la règle de fer du Web de rediriger lorsque le POST réussit.

Ensuite, nous allons concevoir les résultats de la destination de la redirection.

def results(request, poll_id):
    pobject = get_object_or_404(Poll, pk=poll_id)
    return render_to_response('polls/results.html', {'poll': pobject})

Créez également un modèle.

results.html ######

<h1>{{ poll.question }}</h1>

<ul>
{% for choice in poll.choice_set.all %}
    <li>{{ choice.choice }} -- {{ choice.votes }}Voter</li>
{% endfor %}
</ul>

<a href="/polls/{{ poll.id }}/">Votez-vous toujours?</a>

Ce qui précède est le résumé du tutoriel. Cependant, dans ce cas, j'utilise souvent des raccourcis. Cela ne m'aiderait pas, alors je l'ai réécrit en un qui n'utilise pas de raccourcis.

views.py ######

from polls.models import Poll,Choice
from django.http import HttpResponse,HttpResponseRedirect
from django.template import Context,loader,RequestContext
from django.core.urlresolvers import reverse
from django.http import Http404

def index(req):
	latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
	temp = loader.get_template('polls/index.html')
	contxt = Context({
			  'latest_poll_list':latest_poll_list
	})
	return HttpResponse(temp.render(contxt))

def detail(req,poll_id):
	try:
		pobject = Poll.objects.get(pk=poll_id)
	except Poll.DoesNotExist:
		raise Http404
	temp = loader.get_template('polls/detail.html')
	contxt = RequestContext(req,{
			  'poll':pobject
	})
	return HttpResponse(temp.render(contxt))

def results(req,poll_id):
	try:
		pobject = Poll.objects.get(pk=poll_id)
	except Poll.DoesNotExist:
		raise Http404
	temp = loader.get_template('polls/results.html')
	contxt = Context({
		'poll':pobject
	})
	return HttpResponse( temp.render(contxt) )

def vote(req,poll_id):
	try:
		pobject = Poll.objects.get(pk=poll_id)
	except Poll.DoesNotExist:
		raise Http404
	
	try:
		selected_choice = pobject.choice_set.get(pk=req.POST['choice'])
	except (KeyError,Choice.DoesNotExist):
		temp = loader.get_template('polls/detail.html')
		contxt = RequestContext(req,{
			'poll':pobject,
			'error_message':"You have to select choice!"
		})
		return HttpResponse(temp.render(contxt))
	else:
		selected_choice.votes += 1
		selected_choice.save()
		return HttpResponseRedirect( reverse('polls.views.results',args=(pobject.id,) ) )

L'opération Ichiou est également confirmée.

Ce avec quoi j'ai eu du mal était de savoir où placer le contexte_instance qui est inclus comme troisième argument dans le render_to_response de detail et vote. Résolu en écrivant RequestContext (request, {'name': value}).

Même ainsi, j'ai écrit la même chose plusieurs fois et ce n'est pas cool. J'ai réussi à comprendre le flux, et il est peut-être temps d'utiliser le raccourci.

La prochaine fois, j'utiliserai la vue générique.

Recommended Posts

Remarque DJango: depuis le début (traitement de formulaire)
Remarque DJango: depuis le début (en utilisant une vue générique)
Remarque DJango: depuis le début (création d'une vue à partir d'un modèle)
DJango Memo: Depuis le début (préparation)
Remarque DJango: depuis le début (Simplification et fractionnement d'URLConf)
DJango Memo: depuis le début (réglage du modèle)
Récupérez uniquement le texte du formulaire Django.
DJango Memo: depuis le début (création d'une vue)
DJango Memo: depuis le début (réglage de l'écran d'erreur)
DJango Memo: depuis le début (plus de modifications sur l'écran de gestion)
Django Note 4
Django Note 5
Mémo DJango: Depuis le début (en utilisant l'écran de gestion) mon point addictif
Django Note 1
Django Note 3
Django Note 2
Notes d'apprentissage depuis le début de Python 1
Omettre la nomenclature depuis le début de la chaîne
Notes d'apprentissage depuis le début de Python 2
Mémo DJango: Depuis le début (édition de l'écran de gestion) Il y a un mystère
Formulaire de demande Django 2
[Django] Créez un formulaire qui remplit automatiquement l'adresse à partir du code postal
Trouver le début de l'avenomics à partir du grossissement NT 2
Formulaire suggéré par Django
Ramasser les oreilles tombées de Django Form
Formulaire de contact Django
Le mur lors du passage du service Django de Python 2.7 à la série Python 3
Apprenez Nim avec Python (dès le début de l'année).
Étude depuis le début de Python Hour1: Hello World
Compréhension mathématique de l'analyse en composantes principales depuis le début
Définissez DateField du formulaire sur type = date dans Django
[Version 2020] Grattage et traitement du texte d'Aozora Bunko
Étude de Python Hour8: Utilisation de packages
[Django] Donne à Form une valeur initiale dynamique de Model
Le début de cif2cell
[Note] Début de la programmation
Note du didacticiel Django Girls
L'histoire du champ de modèle Django disparaissant de la classe
Points à noter lors de la suppression de plusieurs éléments de la liste
Comment effectuer les réglages initiaux à partir de la création de projet Django