Ceci est un matériel pour les sessions d'étude. J'expliquerai en suivant le tutoriel de django1.8. https://docs.djangoproject.com/en/1.8/intro/tutorial04/
La version 1.4 étant la dernière version du document officiel japonais, il existe quelques différences, mais le flux général est le même, c'est donc une bonne idée de le lire. http://django-docs-ja.readthedocs.org/en/latest/intro/tutorial04.html
Tutoriel 1 Tutoriel 2 Tutoriel 3
Source: 99b01e3
→ 49d2e35
Tout d'abord, réécrivons detail.html
pour voter selon le tutoriel original afin que vous puissiez voter.
polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'poll_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>
Puisque l'URL n'est pas nommée space,
polls: vote
est réécrit enpoll_vote
.
Je n'ai pas encore défini d'url nommée polls_vote, donc si j'ouvre le navigateur tel quel, une erreur se produira. Pour le moment, réécrivons urls.py et views.py et préparons uniquement le skin.
polls/views.py
...
def vote(request, pk):
pass
polls/urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'(?P<pk>\d+)/$', views.detail, name='poll_detail'),
url(r'(?P<pk>\d+)/vote$', views.vote, name='poll_vote'),
]
Vérifiez l'écran des détails sur le navigateur.
C'est un sentiment agréable. À propos, comme la fonction de vote n'est pas implémentée, une erreur se produira si vous appuyez sur le bouton.
Revenons un peu en arrière et expliquons le code en html.
La balise {% if%}
n'a pas encore été émise, mais error_message est passé tel quel, et s'il y a une valeur, le bloc jusqu'à {% endif%}
est sorti.
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
La balise {% csrf_token%}
est, comme son nom l'indique, une balise permettant de définir le jeton csrf.
Il doit être défini dans la balise <form method =" post ">
.
Si vous oubliez de définir cette balise, une exception csrf se produira.
[wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3% 83% 88% E3% 83% AA% E3% 82% AF% E3% 82% A8% E3% 82% B9% E3% 83% 88% E3% 83% 95% E3% 82% A9% E3% 83% De BC% E3% 82% B8% E3% 82% A7% E3% 83% AA)
Les falsifications de requêtes intersites (abréviation: CSRF ou XSRF) sont l'une des méthodes d'attaque du WWW.
Les dommages spécifiques incluent l'affichage involontaire sur le tableau d'affichage et les achats dans les boutiques en ligne. En outre, si l'interface Web des périphériques d'information tels que les routeurs et les réseaux locaux sans fil est la cible d'attaques, on craint que les paramètres de ces périphériques puissent être modifiés sans autorisation.
En bref. Cela garantit que les données ont été envoyées à partir de la page d'entrée légitime. Afin d'éviter que des données ne soient envoyées par POST à partir d'autres sites, le jeton est intégré dans la page d'entrée.
Source: 49d2e35
→274bd82
Modifions la fonction de vote. Même ainsi, il s'agit presque d'une copie du didacticiel original. La destination de la redirection est la page de résultats dans la famille principale, mais cette fois, j'essaie de la passer à l'écran de liste.
polls/views.py
from django.shortcuts import redirect
from .models import Choice
...
def vote(request, pk):
question = get_object_or_404(Question, pk=pk)
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 redirect('index')
Une petite explication du code.
selected_choice = question.choice_set.get(pk=request.POST['choice'])
Il y a une description de choice_set
, qui est un gestionnaire pour manipuler le modèle Choice qui a une relation avec l'objet question.
question.choice_set
et Choice.objects.filter (question = question)
ont la même signification.
Si vous ne comprenez pas le sens, veuillez le laver légèrement.
La valeur publiée est stockée dans request.POST
dans un format de type dictionnaire.
Puisque la valeur d'attribut de nom de la balise d'entrée est «choice», vous pouvez la sélectionner avec request.POST [«choice»].
Sur la ligne suivante
except (KeyError, Choice.DoesNotExist):
Ici, j'écris le traitement lorsqu'il n'y a pas d'entrée de choix (KeyError) et lorsqu'une valeur autre que le choix est lancée (DoesNotExist).
Dans cet exemple, message_erreur est inséré et la page d'entrée s'affiche à nouveau.
La clause ʻelse: `entrera si vous avez un choix réussi pour l'affichage. Les votes (nombre de publications) du choix sélectionné sont incrémentés et enregistrés, et le saut à la page de liste est effectué.
Dans le didacticiel d'origine
return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
Bien qu'il soit écrit comme, ici la fonction redirect
est utilisée. Ce que vous faites est exactement la même chose.
Source: 274bd82
→ 4ecb885
Créons une page de résultats appropriée au lieu d'un écran de liste. Comme d'habitude, html est un copier-coller du tutoriel d'origine.
polls/templates/polls/results.html
<html>
<body>
<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 'poll_detail' question.id %}">Vote again?</a>
</body>
</html>
Ensuite, ajoutez la fonction de résultats à views.py. Le contenu est presque le même que celui des détails, seul le chemin html est modifié.
polls/views.py
def results(request, pk):
obj = get_object_or_404(Question, pk=pk)
return render(request, 'polls/results.html', {
'question': obj,
})
Enfin, modifiez l'url et connectez les vues pour terminer.
polls/urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'(?P<pk>\d+)/$', views.detail, name='poll_detail'),
url(r'(?P<pk>\d+)/vote$', views.vote, name='poll_vote'),
url(r'(?P<pk>\d+)/results$', views.results, name='poll_results'),
]
La page de résultats est prête.
Comme il était censé passer à la page de liste après la publication, corrigeons-le pour qu'il saute à la page de résultats.
Notez que contrairement à la page de liste, poll_results
nécessite un argument.
polls/views.py
def vote(request, pk):
...
return redirect('poll_results', pk)
Vous pouvez maintenant accéder à la page de résultats après la publication.
Document → https://docs.djangoproject.com/en/1.8/intro/tutorial04/#use-generic-views-less-code-is-better Documentation View basée sur les classes → https://docs.djangoproject.com/en/1.8/topics/class-based-views/
À propos des vues couramment utilisées telles que l'affichage de la liste des modèles, l'affichage détaillé, la spécification du modèle, etc. django fournit une vue générale basée sur les classes.
ʻIndex,
detail,
results` dans views.py que j'écris maintenant ont un petit nombre de lignes, donc il peut être difficile de ressentir les avantages, mais Form est impliqué comme vote etc. et c'est un peu compliqué Quand il s'agit de, cela devient un outil très puissant.
La classe Form n'ayant pas encore été mentionnée dans le didacticiel, je n'ai pas changé la source cette fois. Je ne le présenterai qu'en regardant le tutoriel original.
La conversion de vue basée sur les classes sera effectuée dans le prochain (ou prochain) didacticiel, donc si vous n'êtes pas intéressé, veuillez l'ignorer.
TemplateView
Bien que ce ne soit pas dans le didacticiel d'origine, il s'agit d'une vue simple qui ne définit que le modèle à utiliser.
Vous pouvez l'utiliser simplement en définissant le modèle à utiliser.
Remplacez la méthode get_context
pour définir le dictionnaire à transmettre au modèle.
Toutes les vues basées sur les classes doivent être fonctionnalisées en utilisant la méthode ʻas_view () `, car vous devez passer la fonction view à url.
app/views.py
from django.views.generic import TemplateView
class Index(TemplateView):
template_name = 'app/index.html'
index = Index.as_view()
C'est comme ça.
Les propriétés de classe telles que template_name peuvent également être transmises au moment de as_view. En d'autres termes, sans changer views.py, appliquez-le comme ceci dans urls.py.
app/urls.py
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='app/index.html'), name='app_index'),
]
DetailView
En plus du modèle à utiliser, spécifiez le modèle à utiliser.
app/views.py
from django.views.generic import DetailView
from .model import AppModel
class Detail(DetailView):
template_name = 'app/detail.html'
model = AppModel
detail = Detail.as_view()
Bien entendu, cette classe peut également être écrite directement dans urls.py.
Le modèle est nommé ʻobject (et le nom du modèle en lettres minuscules, comme ʻapp model
).
L'objet acquis est passé.
Par défaut, il est appelé depuis urls.py avec le nom pk
.
Si l'objet n'est pas trouvé, Http404 sera déclenché.
ListView
Le détail est un objet unique d'un modèle, tandis que ListView renvoie plusieurs objets.
L'objet à renvoyer est spécifié en passant la propriété queryset
ou en remplaçant la méthode get_queryset
.
app/views.py
from django.views.generic import ListView
from .model import AppModel
class Index(ListView):
template_name = 'app/index.html'
queryset = AppModel.objects.all()
Cette classe a divers éléments de personnalisation tels que la pagination et l'ordre.
--
Dans le didacticiel d'origine, le test est expliqué ensuite, mais Dans le prochain didacticiel, je vais faire un détour et expliquer la classe Form et la classe ModelForm.
Recommended Posts