C'est un matériau pour les sessions d'étude Cette fois, je vais expliquer Form un peu en marge du tutoriel original. Avant d'entrer dans le formulaire, je vais vous présenter un peu la mise à jour de django et de l'espace de noms d'url.
Tutoriel Tutoriel Tutoriel 1 Tutoriel 2 Tutoriel 3 Tutoriel 4
Aussi, jusqu'à la dernière fois, j'ai expliqué django1.8, mais depuis que django1.9 est sorti alors que je sautais les mises à jour. Dans les tutoriels suivants, nous expliquerons django 1.9. Même si vous changez la version de django de 1.8 à 1.9, il n'y a pas de différence particulière dans le contenu des tutoriels 1 à 4.
Source → ʻee195d1`
Vous pouvez mettre à jour vers la dernière version de django (1.9.2 au 20 février 2016) en tapant la commande suivante sur la ligne de commande.
Si vous utilisez un environnement virtuel, n'oubliez pas d'activer l'environnement virtuel avec workon
.
(tutorial)$ pip install --upgrade django
(tutorial)$ pip install --upgrade django
Collecting django
Using cached Django-1.9.2-py2.py3-none-any.whl
Installing collected packages: django
Found existing installation: Django 1.8.6
Uninstalling Django-1.8.6:
Successfully uninstalled Django-1.8.6
Successfully installed django-1.9.2
S'il se termine normalement, il désinstallera le django déjà installé (1.8.6 dans ce cas) comme décrit ci-dessus, et installera le dernier django.
requirements.txt Dans ce didacticiel, django est la seule bibliothèque externe utilisée jusqu'à présent, mais le nombre de bibliothèques associées utilisées dans le futur augmentera régulièrement. Quelle bibliothèque utilisez-vous à ce moment-là? , La version de la bibliothèque est-elle la même? Il est difficile de vérifier à chaque fois. Heureusement, python a un système de gestion de paquets appelé «pip» et un environnement virtuel appelé «virtualenv». Vous ne souffrirez pas souvent de ce problème.
Pour obtenir une liste des bibliothèques utilisées dans l'environnement actuel, tapez la commande suivante dans le shell.
(tutorial)$ pip freeze
Django==1.9.2
wheel==0.24.0
Par convention en python, ce contenu est généré en tant que requirements.txt
.
Une autre personne peut installer les bibliothèques requises en important ce fichier.
Comme vous pouvez le voir, le contenu de sortie a également un numéro de version tel que 1.9.2, il n'y a donc pas lieu de s'inquiéter des dysfonctionnements dus aux différentes versions.
J'avais l'intention de le mettre dans le tutoriel, mais je ne l'ai pas créé, donc je l'ai ajouté avec commit: ʻee195d1`.
(tutorial)$ pip freeze > requirements.txt
Redirigez simplement le contenu de pip freeze
.
Dans le cas de django, il est recommandé de le mettre dans la même hiérarchie que manage.py
.
Utilisez la commande pip install -r
pour importer.
Après avoir confirmé qu'il est workon
dans l'environnement que vous souhaitez importer, après -r
Décrivez le chemin vers le fichier que vous souhaitez importer (requirements.txt
).
(tutorial)$ pip install -r requirements.txt
Si vous avez déjà installé une bibliothèque et souhaitez mettre à jour sa version
(tutorial)$ pip install -U -r requirements.txt
Vous avez besoin de l'option-U
comme>. Cependant, quand je l'ai essayé à portée de main, il semble que si la version de pip est8.0.2
, elle sera mise à jour sans l'ajouter.
Source → bba5e4f
Dans le didacticiel 3, j'ai ignoré l'explication de la conversion de l'espace de noms d'URL.
Compte tenu de l'avenir, il est pratique de les séparer, alors définissez l'espace de noms dans l'url du sondage.
Pour l'ajouter, ajoutez simplement namespace
à l'argument de la fonction ʻinclude`.
tutorial/urls.py
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^polls/', include('polls.urls')),
]
↓ Ajoutez namespace
à l'argument include des sondages
tutorial/urls.py
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^polls/', include('polls.urls', namespace='polls')),
]
Veillez à ne pas confondre la position de la parenthèse fermante avec un argument de la fonction url
Si vous définissez l'espace de noms, vous pouvez extraire l'URL sous la forme de namespace: hoge
.
L'espace de noms peut également être écrit dans une hiérarchie plus élevée, telle que ʻapi: polls: create. J'ai ajouté le préfixe
poll_ au nom de la destination d'inclusion
polls / urls.py`,
Si vous utilisez un espace de noms, il ne sera pas nécessaire, supprimez-le.
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'),
]
↓ Puisque l'espace de noms est coupé, le préfixe nommé poll_
devient inutile.
polls/urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'(?P<pk>\d+)/$', views.detail, name='detail'),
url(r'(?P<pk>\d+)/vote$', views.vote, name='vote'),
url(r'(?P<pk>\d+)/results$', views.results, name='results'),
]
Dans django 1.9, au lieu d'écrire le nom de l'espace de noms dans l'argument include dans
tutorial / urls.py
Il peut également être défini en écrivant ʻapp_name = 'polls'dans
polls / urls.py`. https://docs.djangoproject.com/en/1.9/releases/1.9/#passing-a-3-tuple-or-an-app-name-to-include
Avec ce changement, l'URL est maintenant extraite du nom vers polls: detail
au lieu de poll_detail
.
Veuillez vérifier la différence de source pour la pièce corrigée.
En coupant l'espace de noms, l'application polls
sera plus séparée du projet tutorial
et sera plus facile à utiliser dans d'autres projets.
Avec la méthode précédente, si une autre application du même projet donne un nom tel que poll_detail
à l'URL, une erreur se produit.
Vous devez faire attention aux noms d'URL de toutes les applications gérées par le projet.
D'un autre côté, utilisez l'espace de noms pour éviter les conflits de namespace
dans root urls.py ( tutorial / urls.py
).
Il faut juste faire attention.
Maintenant, entrons enfin dans l'histoire de Form. Le formulaire est utilisé pour transmettre des données dans un certain format du client au serveur, comme le signifie la traduction anglaise de «formulaire, formulaire de demande». Dans le didacticiel 4, le formulaire a été écrit directement dans le modèle et le traitement après réception a été écrit du côté de la vue. Cependant, le modèle et la vue correspondent à la vue et au contrôleur dans le modèle MVC, et il n'est pas bon que la logique soit incluse ici. Aussi, dans le format actuel, l'affichage du bouton radio est décrit dans le modèle, et sa validation (détermination de l'exactitude des données sélectionnées), En outre, le traitement (traitement de vote) utilisant la valeur d'entrée est décrit dans la vue. Cependant, parce que les éléments d'entrée, leur validation et leur traitement à l'aide des données sont étroitement liés. Je veux les gérer ensemble. La classe Form est préparée dans django, et l'entrée générale (texte, liste de sélection, bouton radio, etc.) et Nous fournissons le validateur (contrôle d'entrée).
La classe Form facilite l'écriture de tests pour Honke Tutorial 5. Vous pouvez facilement augmenter le nombre d'éléments d'entrée, et il sera facile de les réutiliser ailleurs. De plus, en établissant un lien avec la vue générale basée sur les classes, la description de la vue peut être encore réduite et rendue plus facile à comprendre.
Source → 34698a1
Tout d'abord, essayons de créer un formulaire.
Créez un fichier appelé forms.py
dans le dossier de l'application et définissez-y la classe Form.
Pour la classe Form, définissez la classe de champ en tant que membre.
Veuillez vous référer au document officiel pour la classe de champ qui peut être définie.
https://docs.djangoproject.com/en/1.9/ref/forms/fields/
Pour le moment, définissons CharField, qui est un champ de saisie de caractères. CharField doit spécifier le nombre maximum de caractères (max_length) comme argument requis, donc définissez 100 caractères pour le moment.
polls/forms.py
from django import forms
class MyForm(forms.Form):
text = forms.CharField(max_length=100)
Vérifions la sortie pour voir ce qui se passe lorsque nous écrivons ceci.
Démarrez le shell python avec ./manage.py shell
, créez une instance de la classe Form créée précédemment et créez-la.
Imprimons-le.
$ ./manage.py shell
(InteractiveConsole)
>>> from polls.forms import MyForm
>>> f = MyForm()
>>> print(f)
<tr><th><label for="id_text">Text:</label></th><td><input id="id_text" maxlength="100" name="text" type="text" /></td></tr>
Vous pouvez voir que la balise d'entrée de type texte est sortie en tant que sortie. Étant donné que le nom du champ est défini sur «texte», vous pouvez également confirmer que la chaîne de caractères «Texte» apparaît comme étiquette.
Source → 34f4914
Ensuite, rendons la classe Form créée au format html. Tout d'abord, écrivez la création de formulaire et passez au modèle dans views.py.
polls/views.py
from .forms import MyForm
def form_test(request):
form = MyForm()
return render(request, 'polls/form.html', {
'form': form,
})
Ensuite, préparons un modèle.
Puisque nous avons spécifié le chemin du modèle polls / form.html
, l'emplacement du fichier est
Il s'agit de polls / templates / polls / form.html
.
polls/templates/polls/form.html
<html>
<body>
<form>
{{ form }}
</form>
</body>
</html>
Vous devriez maintenant voir la chaîne suivante confirmée dans le shell dans {{form}}
.
<tr><th><label for="id_text">Text:</label></th><td><input id="id_text" maxlength="100" name="text" type="text" /></td></tr>
Enfin, connectez la fonction form_test et l'url.
Ajoutons l'URL à polls / urls.py
.
polls/urls.py
urlpatterns = [
...
url(r'^form$', views.form_test),
...
]
Après avoir écrit jusqu'à présent, démarrez le serveur de test avec ./manage.py runserver
et vérifiez-le avec un navigateur.
url est http: // localhost: 8000 / polls / form
.
écran
C'est une scène meurtrière, mais pour le moment, vous pouvez voir qu'il y a une boîte pour l'entrée.
source html
La source html ressemble à ceci.
Comme prévu, la partie {{form}}
a été remplacée.
Source → 06c8422
Eh bien, la zone de saisie a été créée, mais il n'y a pas encore de processus de réception côté serveur.
Lors de l'envoi de données au serveur avec html, décrivez ** où ** ** comment ** les données sont envoyées dans la balise <form>
.
Écrivez respectivement les attributs «action» et «method».
De plus, pour envoyer, vous devez placer le bouton soumettre
dans la balise <form>
.
Si vous souhaitez recevoir dans la même vue, vous n'avez pas besoin de spécifier «action».
Cette fois, je ne l'écris qu'en caractères vides.
Veuillez noter que csrf_token
est requis lors de l'envoi de données par POST.
Explication de csrf → [Tout le monde aime 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% BC% E3% 82% B8% E3% 82% A7% E3% 83% AA)
Puisque la communication POST est une transmission de données html au serveur (= changement des informations du serveur)
La manière dont elle a été saisie est importante.
Dans django, en ajoutant la balise csrf_token
, vous pouvez garantir que les données ont été saisies sur la page que vous avez préparée.
Le code HTML modifié est le suivant.
polls/templates/polls/form.html
<html>
<body>
<form action="" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="Envoyer"/>
</form>
</body>
</html>
Confirmez que le bouton est affiché dans le navigateur
Même si vous appuyez sur le bouton, rien ne se passe car rien n'est écrit après cela,
Si vous regardez le journal sur l'écran où runsever
est exécuté, vous pouvez confirmer que la communication POST est en cours.
(tutorial)$ ./manage.py runserver 127.0.0.1:13000
Performing system checks...
System check identified no issues (0 silenced).
February 21, 2016 - 16:56:38
Django version 1.9.2, using settings 'tutorial.settings'
Starting development server at http://127.0.0.1:13000/
Quit the server with CONTROL-C.
[21/Feb/2016 17:34:28] "GET /polls/form HTTP/1.1" 200 343 #← Affichage de l'écran
[21/Feb/2016 17:34:30] "POST /polls/form HTTP/1.1" 200 343 #← Cliquez sur le bouton «Envoyer»
Au fait, si vous oubliez d'écrire la balise {% csrf_token%}
en html, ce sera comme ça.
Ce processus de vérification est effectué par MIDDLEWARE, et vous pouvez voir qu'il est défini par défaut en regardant settings.py.
tutorial/settings.py
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', #←←←←←←←← Traitement des chèques CSRF
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
Source → 8ea545ce
Les données POST reçues sont stockées dans la classe de requête avec le nom «POST». Ces données sont transmises à la classe Form, la validité des données est vérifiée et, si elles sont correctes, quelque chose est fait en utilisant ces données.
La vue modifiée ressemble à ceci.
polls/views.py
def form_test(request):
if request.method == "POST":
form = MyForm(data=request.POST) #← Passer les données POST reçues
if form.is_valid(): #← Confirmation de la validité des données reçues
pass #← Traitement lorsque des données correctes sont reçues
else: #← la méthode est'POST'n'est pas=Traitement lorsque la première page est affichée
form = MyForm()
return render(request, 'polls/form.html', {
'form': form,
})
Après avoir reçu les données correctes, les données sont enregistrées dans la base de données, etc. et un traitement tel que la redirection vers une autre page est effectué.
Je n'ai rien fait cette fois.
Vérifions le fonctionnement du navigateur dans cet état.
Vous devriez voir un message d'erreur affiché lorsque vous appuyez sur le bouton Soumettre sans rien entrer dans Texte
.
Source → 5637b54
Vous pouvez modifier le comportement et la sortie d'un champ en passant un argument lors de sa création. Par exemple, passer «required = False» n'entraînera pas d'erreur même s'il n'y a pas de valeur d'entrée dans ce champ. Vous pouvez également changer le caractère de «Texte» en ajoutant l'argument «étiquette». Reportez-vous à ce qui suit pour les arguments qui peuvent être spécifiés. https://docs.djangoproject.com/en/1.9/ref/forms/fields/#core-field-arguments
Cette fois, définissons le "requis" et le "libellé" expliqués plus tôt.
polls/forms.py
class MyForm(forms.Form):
text = forms.CharField(max_length=100, required=False, label='texte')
Texte
est maintenant Texte
.
De plus, je pense que vous pouvez confirmer que le message d'erreur a disparu même si vous avez appuyé sur envoyer sans rien entrer.
Source → 9077adee
Réécrivons le formulaire de vote créé dans le didacticiel 4 à l'aide de la classe Form.
L'entrée requise est un bouton radio permettant de sélectionner la liste de choix associée au modèle «question».
ModelChoiceField peut être utilisé pour sélectionner un modèle.
Ce champ nécessite un jeu de requête pour sélectionner le modèle, mais lors de la définition du champ, pour lequel question
Puisqu'il n'est pas certain qu'il s'agisse d'un formulaire, nous remplacerons la méthode __init__
et la recevrons comme argument.
polls/forms.py
class VoteForm(forms.Form):
choice = forms.ModelChoiceField(
queryset=None,
label='Choix',
widget=forms.RadioSelect(),
empty_label=None,
error_messages={
'required': "You didn't select a choice.",
'invalid_choice': "invalid choice.",
},
)
def __init__(self, question, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['choice'].queryset = question.choice_set.all()
Puisque le widget par défaut de ModelChoiceField est une liste de sélection, spécifiez RadioSelect pour le widget. Réglez le jeu de requêtes sur "Aucun" pour le moment, et écrasez-le avec l'argument dans "init". En définissant error_messages, vous pouvez spécifier des messages d'erreur lorsque diverses valeurs invalides sont entrées. Si non spécifié ici (obligatoire) et si une valeur non sélectionnée est saisie (invalid_choice) Un message d'erreur est défini.
Ensuite, sortons le formulaire créé en réécrivant views.py et les modèles.
polls/views.py
from .forms import VoteForm
def detail(request, pk):
obj = get_object_or_404(Question, pk=pk)
form = VoteForm(question=obj)
return render(request, 'polls/detail.html', {
'form': form,
'question': obj,
})
polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Vote" />
</form>
Vérifier avec le navigateur
Le choix est «Objet de choix».
Comme je l'ai mentionné un peu dans le didacticiel 2, la représentation sous forme de chaîne d'une instance ressemble par défaut à "ModelName object".
Ouvrez models.py et remplacez la méthode __str__
.
polls/models.py
class Choice(models.Model):
...
def __str__(self):
return self.choice_text
Cela a bien changé.
D'ailleurs, contrairement au premier écran, il y a une tache noire supplémentaire devant chaque option, En effet, par défaut, chaque option est séparée par une balise «
». Il est préférable d'éviter l'apparition de points noirs en css, Si vous voulez vraiment changer le html, vous pouvez réécrire le inner_html du moteur de rendu contenu par le widget.
polls/forms.py
class VoteForm(forms.Form):
def __init__(self, question, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['choice'].queryset = question.choice_set.all()
self.fields['choice'].widget.renderer.inner_html = '{choice_value}{sub_widgets}<br>'
Source → 56f2b498
Dans le Tutoriel 4, nous avons fourni une fonction pour recevoir des votes appelée «vote», mais elle n'a pas besoin d'être séparée.
Décrivons le traitement des branches lorsque POST
est terminé, comme lors de l'écriture avec form_test
.
polls/views.py
def detail(request, pk):
obj = get_object_or_404(Question, pk=pk)
if request.method == "POST":
form = VoteForm(question=obj, data=request.POST)
if form.is_valid():
# TODO:Processus de vote
return redirect('polls:results', pk)
else:
form = VoteForm(question=obj)
return render(request, 'polls/detail.html', {
'form': form,
'question': obj,
})
N'oubliez pas de corriger le côté html pour qu'il saute aux détails au lieu de voter.
polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Vote" />
</form>
Effacer en action. Au fait, ʻerror_message` est également supprimé car la classe Form émet automatiquement.
Source → 38eb2ec47
C'est finalement le dernier travail.
Déplaçons le processus de vote (le processus d'ajout de +1 aux votes du choix sélectionné et d'enregistrement) qui a été fait dans views.vote
vers la classe Form.
Ce que tu veux faire
polls/views.py
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('polls:results', pk)
Alors, écrivez un processus pour incrémenter les votes de l'instance Choice sélectionnée dans la classe Form.
Lorsque la classe Form exécute ʻis_valid () , les données obtenues en convertissant la valeur d'entrée dans un format approprié seront incluses dans
cleaning_data. C'est un peu déroutant, mais sélectionnez-le dans html avec le bouton radio et sélectionnez-le. Les données transmises au serveur sont une représentation de caractères pk de l'instance de Choice, telle que "" 2 "ou" 3 "". Lorsque vous exécutez ʻis_valid ()
, il sera converti en une instance de ** Choice et placé dans ** dans cleaning_data.
clean_data
est au format dictionnaire avec chaque nom de champ comme clé, donc pour prendre une instance de choix
Écrivez comme self.cleaned_data ['choice']
.
Sur la base de ce qui précède, si vous écrivez une méthode vote
qui incrémente les votes de l'instance Choice sélectionnée, ce sera comme suit.
polls/forms.py
class VoteForm(forms.Form):
...
def vote(self):
assert(self.is_valid())
choice = self.cleaned_data['choice']
choice.votes += 1
choice.save()
assert est écrit pour clarifier que is_valid () a été exécuté et que la valeur d'entrée doit être valide.
Une fois la méthode de vote créée, appelez-la du côté de la vue.
polls/views.py
def detail(request, pk):
obj = get_object_or_404(Question, pk=pk)
if request.method == "POST":
form = VoteForm(question=obj, data=request.POST)
if form.is_valid():
form.vote() #←←←←←←←←←←←← Ajouter ceci
return redirect('polls:results', pk)
else:
form = VoteForm(question=obj)
return render(request, 'polls/detail.html', {
'form': form,
'question': obj,
})
Ceci termine le processus. Puisque views.vote n'est plus nécessaire, supprimons-le. N'oubliez pas de le supprimer également de urls.py.
Le champ correspond aux données conservées en interne.
Par exemple, dans le cas de CharField
, les données internes (nettoyées_données) sont de type texte.
Si c'est ʻIntegerField, ce sera un type numérique, et s'il s'agit de
ModelChoiceField` comme cette fois, ce sera une instance du modèle sélectionné.
D'autre part, le widget est une interface graphique qui spécifie le type de pièces à afficher dans le navigateur.
Dans le cas de ModelChoiceField
, il s'agit d'une liste de sélection par défaut, mais vous pouvez la changer en un bouton radio comme cette fois.
Il est également possible de créer la zone de texte (bien que ce soit la pire en entrée) et de saisir directement le pk de Choice.
Il existe également un widget qui vous permet de saisir la date et l'heure séparément, tel que SplitDateTimeWidget
.
Il est facile de se tromper au début, mais décidons lequel changer en considérant si vous souhaitez modifier les données internes ou l'affichage sur le navigateur.
Source → 7d19e395
FormView est fourni comme une vue à usage général dans django. Tout d'abord, réécrivons form_test en utilisant cette classe.
À propos, la fonction form_test à réécrire est divisée en plusieurs processus bien qu'elle soit courte.
polls.py
def form_test(request):
if request.method == "POST": #Traitement à la réception par la méthode POST
form = MyForm(data=request.POST) #Processus de création de formulaire (+Transmettez les données reçues à Form)
if form.is_valid():
pass #Traitement lorsque la valeur d'entrée du formulaire est correcte
else: #Traitement à la réception par la méthode GET
form = MyForm() #Processus de création de formulaire (pas de données)
return render(request, 'polls/form.html', { #Rendu du modèle
'form': form,
})
Il a été foiré avec des commentaires, mais tout d'abord, il peut être divisé en gros selon qu'il a été appelé par GET
ou POST
.
Dans le cas de GET
, c'est le processus lorsque la page est affichée en premier, il n'y avait donc aucun argument lors de la création du formulaire.
D'autre part, dans le cas de «POST», il existe un processus pour recevoir les données d'entrée après avoir affiché la page une fois.
Data = request.POST
est passé comme argument de Form.
De plus, la validité de ces données est jugée (form.is_valid ()
), et si elle est correcte, un traitement sera effectué.
Dans la classe FormView fournie par django, chacun de ces processus est une méthode.
Vous pouvez modifier le traitement de la pièce concernée en remplaçant une méthode spécifique.
Voici une liste des méthodes à remplacer lors de la modification de l'opération à titre d'exemple.
(Il existe d'autres méthodes dont dispose la vue de base (comme une méthode qui appelle get quand GET))
Méthodes qui peuvent être remplacées dans FormView
def get(self, request, *args, **kwargs): #Appelé à l'accès avec la méthode GET
def post(self, request, *args, **kwargs): #Appelé à l'accès avec la méthode POST
def put(self, *args, **kwargs): #Appelé à l'accès avec la méthode PUT
def get_initial(self): #Définir la valeur initiale de Form
def get_prefix(self): #Définir le préfixe du formulaire
def get_form_class(self): #Obtenez la classe Form à utiliser
def get_form_kwargs(self): #Récupère les arguments à transmettre à la classe Form
def get_form(self, form_class=None): #Obtenir une instance de la classe Form
def get_success_url(self): #URL à rediriger en cas de réussite
def form_valid(self, form): #Traitement normal
def form_invalid(self, form): #Que faire si les données sont incorrectes
def get_context_data(self, **kwargs): #Obtenez le contexte à transmettre au modèle
def render_to_response(self, context, **response_kwargs): #Créer une réponse
def get_template_names(self): #Obtenez le nom du modèle utilisé pour le rendu
Il existe des méthodes appelées
get_form_class
etget_template_names
pour spécifier la classe et le modèle Form à utiliser. Au lieu de remplacer cette méthode, il suffit de spécifier des valeurs de champ telles queform_class
ettemplate_name
.
Pour une page de formulaire simple, ce que vous spécifiez
form_class
: classe de formulaire à utiliser
template_name
: modèle utilisé pour le rendu
success_url
: URL vers laquelle passer en cas de succès
Il n'y en a que trois.
form_valid
.success_url est une spécification de chaîne de caractères. Si vous souhaitez utiliser le nom défini dans l'URL, utilisez le résolveur. Puisqu'il n'est pas possible de définir un champ avec resol_url lors de la définition d'une classe, utilisez
reverse_lazy
ou Il remplaceraget_success_url
.
Le form_testh réécrit est le suivant.
polls/views.py
from django.views.generic import FormView
from django.core.urlresolvers import reverse_lazy
from .forms import MyForm
...
class FormTest(FormView):
form_class = MyForm
template_name = 'polls/form.html'
success_url = reverse_lazy('polls:index')
form_test = FormTest.as_view()
Supprimez le
def form_test (request):
que vous avez créé en premier car il est inutile. Conflit de noms et une erreur se produit.
Lors de l'utilisation d'une vue basée sur les classes, comme la source ci-dessus
Exécutez view name = class name.as_view ()
après avoir défini la classe.
La fonction form_test
que j'ai écrite au début contenait des instructions if pour le jugement de méthode et le jugement de données.
Si vous utilisez FormView, le jugement sera poussé dans la classe Super, donc
J'ai pu créer une vue sans instruction if (= logique).
Source → 1efe74c527
Enfin, réécrivons la fonction de détail en une vue basée sur les classes. Tout d'abord, c'est assez compliqué pour ne pas convenir aux tutoriels. Il y a deux raisons
Question
comme argument de la classe FormSi c'est seulement 1, l'histoire est facile, et il y a un DetailView
pour afficher la page de détail d'une instance.
L'affichage est terminé simplement en spécifiant le modèle et le modèle à utiliser dans cette classe, tout comme FormView
.
Bien sûr, vous pouvez changer le nom de l'argument reçu par \ # view (maintenant pk) et le nom de l'objet passé au modèle.
\ # De plus, (* app_name * / * model_name * _detail.html) est utilisé par défaut même si vous ne spécifiez pas de modèle.
De plus, pour le n ° 2, il est facile d'augmenter les arguments de la classe Form (il suffit de remplacer get_form_kwargs
).
Le fait que vous ayez besoin d'une instance "Question" complique l'histoire.
Puisque SingleObjectMixin
est préparé comme un mixin de la classe View qui acquiert une instance d'un certain modèle,
Cette fois, nous utiliserons ce Mixin et FormView en combinaison.
def detail(request, pk): obj = get_object_or_404(Question, pk=pk) if request.method == "POST": form = VoteForm(question=obj, data=request.POST) if form.is_valid(): form.vote() return redirect('polls:results', pk) else: form = VoteForm(question=obj) return render(request, 'polls/detail.html', { 'form': form, 'question': obj, })
Détail avant réécriture
↓ Réécriture en utilisant la classe
#### **`polls/views.py`**
```python
from django.shortcuts import resolve_url
from django.views.generic import FormView
from django.views.generic.detail import SingleObjectMixin
from .forms import VoteForm
from .models import Question
...
class Detail(SingleObjectMixin, FormView):
model = Question
form_class = VoteForm
context_object_name = 'question'
template_name = 'polls/detail.html'
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
return super().post(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['question'] = self.object
return kwargs
def form_valid(self, form):
form.vote()
return super().form_valid(form)
def get_success_url(self):
return resolve_url('polls:results', self.kwargs['pk'])
detail = Detail.as_view()
Tout d'abord, vous avez besoin d'une instance de «Question» à la fois pour «GET» et «POST».
self.object = self.get_object()
J'essaye d'appeler.
La classe de modèle à acquérir par cette méthode est spécifiée par model = Question
.
Puisque nous utilisons une instance Question
avec le nom question
dans le modèle,
Le nom est spécifié par context_object_name = 'question'
.
Parce que cette instance est nécessaire comme argument de VoteForm
Remplacer get_form_kwargs
et ajouter l'argument question
.
Je veux voter si les données sont correctes, alors remplacez form_valid
et
J'essaye d'appeler «form.vote».
Enfin, nous remplaçons get_success_url
pour réécrire l'URL de destination.
Puisque l'argument reçu par view est dans self.kwargs
, le pk reçu de l'URL avec` self.kwargs ['pk'] ʻest passé à l'URL de résultat.
"Ce n'est pas beaucoup plus simple que la première fonction detail
, cela semble plus compliqué, mais est-ce normal d'en faire une classe?"
Ceux qui pensent avoir oublié l'important.
Les classes sont ** héritées et réutilisées **.
Si vous créez une autre classe View avec cette classe en tant que super classe, tout comme vous avez créé la classe Detail en héritant de FormView
Lors de l'écriture d'une vue qui effectue le même traitement, vous pouvez facilement créer une vue qui effectue la même opération simplement en réécrivant quatre champs tels que modèle
.
Si vous écrivez une vue en tant que fonction, veuillez saisir cette occasion pour envisager de passer à une vue basée sur les classes.
Ensuite, nous utiliserons bootstrap pour nettoyer la conception.
Recommended Posts