À partir de Dernière fois, nous allons continuer avec le tutoriel Django. Cette fois, je parlerai de la vue basée sur les classes, qui est un point important lors de l'utilisation de Django.
<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>
Par exemple, supposons que vous souhaitiez créer un formulaire comme celui-ci.
C'est un formulaire qui prépare une réponse avec un bouton radio pour une certaine question, la vérifie et l'envoie par POST.
{{forloop.counter}}
est le nombre de boucles pour {% pour le choix dans question.choice_set.all%}
.
La notation réelle serait, par exemple, <input type =" radio "name =" choice "id =" choice1 "value =" 1 ">
.
Jetons un coup d'œil à la vue pour cela.
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
#Le code ci-dessus provoque des problèmes de conflit, donc F(Nom de colonne)Utilisez la méthode.
selected_choice.votes = F('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,)))
La différence par rapport à la dernière fois est que les objets HttpResposeRedirect
et reverse
ont été importés.
La première est une méthode de redirection, et la seconde méthode reverse ()
est une méthode qui renvoie une URL et appelle l'URL à partir du chemin nommé défini dans urls.py. Par exemple, dans le cas ci-dessus
L'URL / polls / results
est renvoyée, mais vous pouvez renvoyer l'URL / polls / 1 / results
en spécifiant question.id comme argument.
Si vous comprenez le contenu de la fonction de vote elle-même jusqu'à la dernière fois, il n'est pas si difficile de comprendre ce que vous faites.
Tout d'abord, affectez une instance à la variable. Puisqu'il s'agit d'une méthode get_object_or_404
, il s'agit d'une instance des données de clé primaire correspondantes du modèle Question
.
Nous le traiterons comme une exception avec le modèle try-catch-else
.
Tout d'abord, sur la base des données POST envoyées depuis le formulaire, la méthode get ()
est utilisée pour obtenir les données de la base de données.
request.POST
vous permet d'accéder aux données envoyées avec la clé spécifiée.
Par exemple, dans ce cas de request.POST ['choice']
, cela signifie accéder aux données dont l'attribut name
est choice
.
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
Ce sera cette partie.
Donc, cette fois, c'est un formulaire avec un bouton radio, donc il y a des choix dans la boucle for
, mais comme il n'y a qu'une seule donnée à envoyer, la valeur de la valeur
du choix est retirée et transformée en pk
. Devenir.
Au fait, s'il y a plusieurs mêmes attributs name
tels que des cases à cocher, veuillez utiliser getlist () ʻau lieu de
get (). Parole silencieuse, par exemple,
question.choice_set.get (pk = request.POST ['choice'])devient
question.choice_set.get (pk = 1), c'est-à-dire que les données avec la clé primaire 1 sont
choice Il sera recherché dans le modèle et assigné à la variable en tant qu'instance. S'il peut être obtenu en toute sécurité, il passera à ʻelse
, s'il ne peut pas être obtenu, il sera traité comme une exception de KeyError
, et le message d'erreur sera retourné par la méthode render ()
et renvoyé à l'écran de formulaire.
Le processus de ʻelse` consiste à augmenter le décompte du nombre de votes, à le mettre à jour dans la base de données et à rediriger vers l'écran des résultats du vote.
Créons maintenant un modèle pour les résultats du vote.
<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>
La partie de vote {{choice.votes | pluralize}}
est l'expression qui indique que si la valeur à gauche de pluiralize
est une forme plurielle, un suffixe indiquant la forme plurielle est renvoyé.
Par exemple, dans ce cas, si «choice.votes» vaut 2, alors «vote» devient «votes».
Eh bien, j'ai écrit plusieurs vues (contrôleurs)
jusqu'à présent, mais Django
a une vue intégrée dite à usage général appelée vue basée sur les classes.
view
a le rôle de relier les données et ʻURL` au modèle, mais même si cela est arrivé si loin
-Créer et afficher une liste avec filter ()
-Obtenir les données de la base de données et les refléter dans le modèle
· Afficher l’une des nombreuses pages telles que «sondages / 1 / résultats»
Je pense qu'un tel processus est sorti plusieurs fois et j'ai écrit «view» à chaque fois.
Une vue à usage général est un système qui définit à l'avance les valeurs par défaut appropriées en fonction du modèle et du formulaire afin que vous n'ayez pas à écrire un tel traitement plusieurs fois.
Au fait, comme vous pouvez le voir du fait qu'il est basé sur une classe, la vue générale dans Django
est fournie par la classe.
Il semble qu'il y ait aussi une base de fonctions.
Jetons un œil à la précédente vue
.
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
# Create your views here.
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)
return render(request, 'polls/detail.html', {'question': question})
def results(request, question_id):
response = "You`re looking at the results of question %s."
return HttpResponse(response % question_id)
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 = F('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,)))
Ensuite, voici la nouvelle vue
à écrire
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
# Create your views here.
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:
#Accédez aux données POST. Cette fois, l'ID de l'option sélectionnée par le bouton radio du formulaire est renvoyé sous forme de chaîne de caractères et affecté à la variable.
selected_choice = question.choice_set.get(pk=request.POST['choice'])
#Spécifiez l'erreur de clé dans la spécification d'exception. Traitement des exceptions s'il n'y a pas le choix.
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', { 'question':question, 'error_message':"You didn`t select a choice.",})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
#Rediriger le traitement dans Django. inverser()Dans les URL.Appelez l'URL à partir du chemin nommé défini dans py. Vous pouvez spécifier une page spécifique en spécifiant l'argument.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Vous pouvez voir que c'est tout à fait différent.
Tout d'abord, importez l'objet générique
depuis le module django.views
.
Il peut également être importé et utilisé pour chaque vue basée sur une classe, telle que from django.views.generic import ListView
.
Dans ce cas, l'argument serait «ListView» au lieu de «generic.ListView».
Et comme mentionné ci-dessus, puisqu'il s'agit d'une vue basée sur les classes, nous réécrirons ce qui était précédemment écrit en tant que fonction dans une classe et hériterons et utiliserons chaque vue basée sur les classes.
Par exemple, cela ressemble à class IndexView (generic.ListView):
. Puisqu'il hérite, spécifiez la vue à usage général que vous souhaitez utiliser comme argument.
Bien entendu, l'héritage peut également être remplacé.
Regardons chacun d'eux.
Listview
Listview
est une vue pour afficher une liste d'objets. En d'autres termes, il peut être utilisé lors de la création d'une page de liste.
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]
Lorsque vous l'utilisez réellement, il sera écrit comme ci-dessus.
Normalement, il est essentiel de spécifier le modèle lors de l'utilisation de la vue basée sur les classes, mais vous pouvez également spécifier la méthode de queryset ()
.
Par exemple, dans ce qui précède, au lieu d'afficher simplement la liste des modèles, nous voulons afficher la liste par incréments de 5, donc nous spécifions avec query set ()
au lieu de spécifier le modèle.
Après cela, spécifiez le modèle de la destination de pontage avec template_name
, et décidez du nom de variable de l'objet à la destination de pontage avec context_object_name
.
Hormis le premier, je dois décider du second
{% for question in latest_question_list %}
Où j'écrivais comme ça
{% for question in object_list %}
Si vous ne l'écrivez pas, cela ne fonctionnera pas. Il va sans dire lequel est le plus facile à comprendre à première vue. D'ailleurs, en utilisant un mécanisme appelé «Processeur de contexte», vous pouvez définir une variable de modèle dans un fichier séparé et l'importer afin que vous n'ayez pas à la spécifier individuellement ici. Il peut également être utilisé comme une variable globale dans un modèle. Référence: Présentation de Google Analytics à Django
DetailView
DetailView
est une vue basée sur les classes qui peut être utilisée pour des pages de détails individuelles.
La vue que vous souhaitez utiliser pour des pages telles que sondages / 1 / détail
.
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
Vous pouvez voir que vous spécifiez le modèle et le modèle.
En plus de cela, vous devez spécifier pk
ou slug
dans ʻurls.py, mais cette fois, spécifiez
pk` après cela.
Ce sont les deux vues basées sur les classes utilisées dans ce didacticiel, mais il y en a plusieurs autres, donc cette fois, nous allons simplement jeter un coup d'œil à ce qu'elles ont.
generic.base.View
Il s'agit de la classe principale de la vue basée sur les classes. Chaque base de classe en hérite et en héritant, nous utilisons la base de classe.
Exemple d'utilisation
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request, *args, **kwargs):
return HttpResponse('Hello, World!')
Les deux peuvent être utilisés pour les formulaires, ce qui donne des vues avec un traitement de mise à jour.
Le rôle de «FormView» est d'afficher le formulaire lorsqu'il reçoit la «méthode HTTP GET», c'est-à-dire d'afficher le formulaire lorsque «l'URL» définie dans «path» est atteinte.
Ensuite, lorsque vous recevez la méthode HTTP POST
, vous pouvez exécuter le processus en fonction de la demande
reçue du formulaire.
Il semble être utilisé pour les formulaires qui effectuent un traitement de redirection sans traitement de base de données supplémentaire,
Par exemple, le formulaire de connexion donné à titre d'exemple a une vue séparée appelée la vue d'authentification appelée LoginView
, il semble donc que cette dernière, qui sera décrite plus loin, est souvent utilisée.
Exemple d'utilisation
from django import forms
class ContactForm(forms.Form):
name = forms.CharField()
message = forms.CharField(widget=forms.Textarea)
def send_email(self):
# send email using the self.cleaned_data dictionary
pass
Pour CreateView
, le processus insert
est exécuté pour le modèle spécifié en fonction de la demande
reçue du formulaire lorsque la méthode HTTP POST
est reçue.
En d'autres termes, il peut être utilisé pour les formulaires qui ajoutent de nouveaux enregistrements (données).
Exemple d'utilisation
from django.views.generic.edit import CreateView
from myapp.models import Author
class AuthorCreate(CreateView):
model = Author
fields = ['name']
ʻUpdateView` n'est pas un ajout, mais une vue utilisée pour les formulaires qui impliquent la mise à jour d'enregistrements existants.
Exemple d'utilisation
from django.views.generic.edit import UpdateView
from myapp.models import Author
class AuthorUpdate(UpdateView):
model = Author
fields = ['name']
template_name_suffix = '_update_form'
Vous pouvez maintenant voir que les variables fields
sont définies dans ʻUpdateView et
CreateView`.
Il s'agit d'un élément qui doit être défini lors de l'utilisation des deux vues, et cela signifie que les données saisies à partir du formulaire sont ignorées sauf pour les champs spécifiés.
En d'autres termes, dans l'exemple ci-dessus, quel que soit le nombre d'éléments d'entrée dans le formulaire correspondant, par exemple, «adresse» ou «Tel», seul le champ «nom» sera ajouté / mis à jour.
Cette spécification peut être définie dans une liste ou une taple, vous pouvez donc en spécifier plusieurs.
Maintenant que nous avons brièvement identifié le rôle de chaque base de classe et confirmé comment le définir, l'étape suivante est de modifier ʻurls.py` pour qu'il puisse utiliser la vue générique.
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'),
]
Auparavant, vous deviez spécifier pk
pour utiliser DetailView
.
Assurez-vous que <int: question_id>
est maintenant <int: pk>
.
Enfin, modifiez views.py
comme décrit au début de cet élément.
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
# Create your views here.
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:
#Accédez aux données POST. Cette fois, l'ID de l'option sélectionnée par le bouton radio du formulaire est renvoyé sous forme de chaîne de caractères et affecté à la variable.
selected_choice = question.choice_set.get(pk=request.POST['choice'])
#Spécifiez l'erreur de clé dans la spécification d'exception. Traitement des exceptions s'il n'y a pas le choix.
except(KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', { 'question':question, 'error_message':"You didn't select a choice.",})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
#Rediriger le traitement dans Django. inverser()Dans les URL.Appelez l'URL à partir du chemin nommé défini dans py. Vous pouvez spécifier une page spécifique en spécifiant l'argument.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
J'ai senti que la compréhension ici est inévitable lorsque l'on traite avec Django.
Présentation de Google Analytics à Django Introduction à la vue générique basée sur les classes dans Django et exemple d'utilisation Collecte des vues de classe génériques de Django et mention de l'implémentation
Recommended Posts