C'est un mémo écrit quand CRUD avec Django. J'ai extrait le contenu qui me convient en me référant à différents sites.
Avant le développement, veuillez également vous référer à ici, qui résume le flux de base et les concepts de développement avec Django (bien qu'il soit un peu écrasé).
Je suis dans un environnement Mac, donc j'essaye sur un Mac, mais je pense que c'est la même chose sur Windows de base.
Python est 3.6.1. Je crée un environnement virtuel en utilisant venv qui est livré en standard avec Python 3.x, mais je pense qu'il n'est pas nécessaire que ce soit un environnement virtuel. Veuillez consulter ici pour la construction de l'environnement.
Le résultat du gel de pip est le suivant.
Django==1.11
django-bootstrap-form==3.2.1
PyMySQL==0.7.11
pytz==2017.2
Puisque pytz est inclus lorsque Django est inclus, il y a trois entrées explicites: Django, django-bootstrap-form et PyMySQL. Veuillez l'installer si nécessaire.
pip install Django
pip install django-bootstrap-form
pip install PyMySQL
django-bootstrap-from est un package pour générer automatiquement des formulaires dans le style de Bootstrap.
Django a le concept de «projet» et d '«application». C'est comme créer d'abord un projet, puis y ajouter une application (ci-après appelée application).
C'est comme une solution et un projet Visual Studio. Comme Ara d'ASP.NET MVC.
Créons maintenant un projet. Ici, nous créons un projet appelé jango_test.
django-admin.py startproject django_test
Lorsque la création est terminée, la structure de fichiers suivante sera générée.
django_test/
manage.py
django_test/
__init__.py
settings.py
urls.py
wsgi.py
Il existe un répertoire portant le même nom que le projet directement sous le répertoire du projet. Il y a un fichier de configuration commun à tous les projets (mais il est déroutant pour l'explication). En règle générale, le travail expliqué ici suppose un travail directement sous le répertoire du projet.
Une fois le projet créé, modifiez les paramètres dans settings.py.
Django est configuré pour utiliser SQLite par défaut, mais comme j'utilise MySQL, j'édite les bases de données en conséquence.
django_test/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djangodb', #Récrire
'USER': 'root', #Récrire
'PASSWORD': 'root', #Récrire
'HOST': '',
'PORT': '',
}
}
Il va sans dire que vous devez configurer MySQL avant de faire cela.
Au début, j'ai installé PyMySQL pour me connecter à MySQL, mais je ne peux pas l'utiliser seul, donc je charge le package dans le projet. Je l'ai écrit au début de settings.py.
Il y avait un article qui a été écrit dans manage.py, mais comme il est lié aux paramètres, je l'ai écrit dans settings.py pour le moment.
django_test/settings.py
import pymysql
pymysql.install_as_MySQLdb()
Comme autres éléments de paramétrage, dépêchez-vous et modifiez LANGUAGE_CODE et TIME_ZONE.
django_test/settings.py
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
L'installation de la base de données étant terminée, nous migrerons une fois ici.
python manage.py migrate
En conséquence, les tables requises pour utiliser Django seront générées dans la base de données spécifiée.
Maintenant, démarrons le serveur Web de développement une fois et voyons si l'écran Django peut être visualisé correctement. Démarrez-le avec la commande suivante.
python manage.py runserver
Une fois le démarrage terminé, essayez d'accéder à l'URL ci-dessous.
http://localhost:8000/
Ce n'est pas grave si vous voyez quelque chose comme "Cela a fonctionné!"
Après avoir défini le projet, créons une application.
Ici, créons une application nommée crud.
python manage.py startapp crud
Un répertoire appelé crud a été créé au même niveau que le répertoire de travail. Les fichiers liés à l'application sont générés en dessous.
Il semble qu'il ne puisse pas être utilisé simplement en générant une application, je vais donc le décrire pour le charger dans le projet. Les paramètres sont définis dans settings.py. Aussi, au fait, chargez le formulaire django-bootstrap qui sera utilisé plus tard.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+ 'bootstrapform',
+ 'crud',
]
Django utilise le modèle MTV au lieu du MVC. Cependant, il n'est pas nécessaire d'apprendre un nouveau concept car c'est juste une image que V de MVC a été renommé T (emplate) et C de VMC a été renommé V (iew).
Créez un modèle de membre avec l'image d'enregistrement des informations de membre. Décrivez comme suit dans models.py sous le répertoire crud.
crud/models.py
from django.db import models
# Register your models here
class Member(models.Model):
name = models.CharField('Nom complet', max_length=255)
email = models.CharField('E-Mail', max_length=255)
age = models.IntegerField('âge', blank=True, default=0)
def __str__(self):
return self.name
Je ne vais pas l'expliquer en particulier, mais je pense que c'est dans la fourchette que je peux imaginer.
Après avoir écrit le modèle, générez un fichier de migration pour la génération de table contenant le modèle. C'est d'abord un soi-disant code. En exécutant des migrations en spécifiant le nom de l'application, il semble qu'un fichier de migration soit créé en analysant les modifications du modèle dans l'application cible.
python manage.py makemigrations crud
Il semble qu'il puisse être utilisé avec des tables existantes.
Exécutez la migration lorsque le fichier de migration est généré.
python manage.py migrate
Dans le développement actuel, "modifier le modèle" ⇒ "meke migration" ⇒ "migrer" sera répété.
Django vous permet d'accéder au site d'administration (modèle) depuis le début en visitant http: // localhost: 8000 / admin. Cependant, comme l'utilisateur et le mot de passe de connexion au site de gestion ne sont pas définis, commencez par le générer et l'obtenir.
Ajoutez un utilisateur avec la commande suivante.
python manage.py createsuperuser
Définissez un mot de passe, une adresse e-mail, etc.
Lorsque vous vous connectez au site de gestion, seuls "Groupe" et "Utilisateur" sont affichés comme cibles de gestion par défaut. Pour gérer votre propre modèle, vous devez ajouter la description nécessaire à admin.py sous le répertoire de l'application.
crud/admin.py
from django.contrib import admin
from crud.models import Member
# Register your models here.
admin.site.register(Member)
Veuillez mettre à jour après avoir ajouté la description ou vous reconnecter pour vérifier les modifications.
Une fois que vous pouvez gérer les membres sur le site d'administration, ajoutez quelques lignes de données pour des tests ultérieurs.
De plus, Django dispose d'une fonction d'import de données appelée firexure.
Dans l'ordre de MVT, j'aimerais jouer avec Templete ensuite, mais pour comprendre la structure de l'application, commencez par définir View (équivalent à Controller) et le routage. Cette fois, je vais le configurer pour que chaque fonction soit accessible avec le modèle d'URL suivant.
Maintenant, écrivons d'abord View. Cependant, avant d'implémenter une fonction spécifique, je voudrais d'abord implémenter une méthode qui renvoie simplement une chaîne de caractères, telle que «list», «edit», «delete», et vérifier le mappage entre l'URL et la fonction.
De plus, la raison pour laquelle il n'y a pas de "nouveau" est que, comme d'autres frameworks, s'il y a un POST et un ID, il sera édité, et s'il ne s'agit que d'un POST, il sera jugé comme un nouvel ajout (car "edit" est utilisé en commun).
Le fichier views.py sous crud devrait ressembler à ceci:
crud/views.py
from django.shortcuts import render
from django.http import HttpResponse
#liste
def index(request):
return HttpResponse("liste")
#Nouveau et modifier
def edit(request, id=None):
return HttpResponse("Éditer")
#Effacer
def delete(request, id=None):
return HttpResponse("Effacer")
#Détails (bonus)
def detail(request, id=None):
return HttpResponse("Détails")
C'est juste un processus qui renvoie une chaîne.
Pour définir le routage dans Django, il semble être une bonne pratique de générer urls.py sous le répertoire de l'application, de définir le ruting dans l'application, puis de l'inclure dans urls.py de l'ensemble du projet et de le définir. est.
Configurez le routage en fonction de l'URL et des règles de la carte des caractéristiques indiquées ci-dessus.
crud/urls.py
from django.conf.urls import url
from crud import views
urlpatterns = [
url(r'^members/$', views.index, name='index'),
url(r'^members/add/$', views.edit, name='add'),
url(r'^members/edit/(?P<id>\d+)/$', views.edit, name='edit'),
url(r'^members/delete/(?P<id>\d+)/$', views.delete, name='delete'),
url(r'^members/detail/(?P<id>\d+)/$', views.detail, name='detail'),
]
Le routage est
url(r'Expression canonique de modèle d'URL', views.Méthode correspondante de py, name='Nom de la route')
Le format est.
La description> r '' semble signifier que les caractères spéciaux ne sont pas échappés dans ''. Le nom de la route est utilisé lors de la spécification de la destination du lien dans le modèle.
Incluez le jeu urls.py dans le répertoire de l'application. Cela entraînera une URL telle que http: // localhost: 8000 / crud / members /.
urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^crud/', include('crud.urls', namespace='crud'))
]
Maintenant, exécutez runserver, accédez à chaque modèle d'URL et voyez comment cela fonctionne (si les caractères appropriés sont affichés).
Ensuite, l'implémentation dans views.py qui a été temporairement implémentée est-elle cette implémentation? Faire.
Décrivez index () comme suit.
crud/views.py
from django.shortcuts import render
from django.http import HttpResponse
from crud.models import Member #ajouter à
#liste
def index(request):
members = Member.objects.all().order_by('id') #Obtenez de la valeur
return render(request, 'members/index.html', {'members':members}) #Passer une valeur au modèle
J'obtiens une valeur pour les membres et je la transmets à membres / index.html avec le nom des membres.
Avant de créer index.html côté réception, créez la partie commune sur chaque page en tant que modèle commun (base.html). Puisque Bootstrap est cette fois utilisé comme framework CSS, les CSS et JS nécessaires sont lus à partir du CDN.
Créez un répertoire appelé Templates sous le répertoire de l'application (crud) et enregistrez-le sous base.html.
crud/templates/base.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}My books{% endblock %}</title>
<!-- Bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
{% block content %}
{{ content }}
{% endblock %}
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!--Où écrire js-->
{% block script %}
{% endblock %}
</body>
</html>
Ceci complète le modèle commun. Décrivez le contenu correspondant à {%%} dans le modèle sur une page distincte.
Créons maintenant une page séparée. Créez un répertoire de membres sous le répertoire de modèles créé précédemment et enregistrez-le sous le nom index.html.
Django ne semble pas avoir de restrictions très strictes sur le nom du répertoire où les modèles sont stockés. Dans les exemples sur le net, beaucoup d'entre eux sont appelés noms d'applications (crud ici). Il semble que ce soit la même chose dans le tutoriel officiel.
crud/templates/members/index.html
{% extends "base.html" %}
{% block title %}
Programmé pour afficher une liste
{% endblock title %}
{% block content %}
<h3>Affichage de la liste</h3>
<a href="{% url 'crud:add' %}" class="btn btn-primary btn-sm">ajouter à</a>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Nom complet</th>
<th>E-Mail</th>
<th>âge</th>
<th>opération</th>
</tr>
</thead>
<tbody>
{% for member in members %}
<tr>
<td>{{ member.id }}</td>
<td><a href="{% url 'crud:detail' id=member.id %}">{{ member.name }}</a></td>
<td>{{ member.email }}</td>
<td>{{ member.age }}</td>
<td>
<a href="{% url 'crud:edit' id=member.id %}" class="btn btn-primary btn-sm">Éditer</a>
<a href="{% url 'crud:delete' id=member.id %}" class="btn btn-primary btn-sm" id="btn_del">Effacer</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!--Mettez la page ici-->
{% endblock content %}
<!--Insérer js-->
{% block script %}
{% endblock %}
Vérifiez si l'écran de liste s'affiche correctement une fois que chaque implémentation est terminée. Cliquez pour voir si les liens des boutons «Enregistrer», «Modifier» et «Supprimer» sont appropriés.
Ensuite, nous allons implémenter de nouvelles fonctions d'ajout / d'édition. Utilisez les mêmes vues.py et modèle pour les nouveaux et les modifier. Dans Django, il semble qu'il soit courant d'utiliser les classes Form et ModelForm qui génèrent automatiquement un formulaire (informations HTML), alors utilisons-le.
La classe Form semble être utilisée pour créer des formulaires (comme la recherche) sans modèle.
Maintenant, créez forms.py sous le répertoire de l'application et écrivez comme suit.
crud/forms.py
from django.forms import ModelForm
from crud.models import Member
class MemberForm(ModelForm):
class Meta:
model = Member
fields = ('name','email','age',)
En plus des détails, j'utiliserai le modèle Member et utiliserai le nom, l'adresse e-mail et l'âge! Est-ce comme une déclaration?
crud/views.py
from django.shortcuts import render, get_object_or_404, redirect #ajouter à
from django.http import HttpResponse
from crud.models import Member
from crud.forms import MemberForm #ajouter à
#(Extrait)
#Nouveau et modifier
def edit(request, id=None):
if id: #Lorsqu'il y a un identifiant (lors de l'édition)
#Rechercher par identifiant et renvoyer les résultats ou erreur 404
member = get_object_or_404(Member, pk=id)
else: #Quand il n'y a pas d'identifiant (quand neuf)
#Créer un membre
member = Member()
#Au POST (lorsque le bouton d'enregistrement est enfoncé, que ce soit nouveau ou modifier)
if request.method == 'POST':
#Générer un formulaire
form = MemberForm(request.POST, instance=member)
if form.is_valid(): #Enregistrer si la validation est OK
member = form.save(commit=False)
member.save()
return redirect('crud:index')
else: #Au moment de GET (générer un formulaire)
form = MemberForm(instance=member)
#Afficher un nouvel écran / modifier l'écran
return render(request, 'members/edit.html', dict(form=form, id=id))
Créez un écran (edit.html) à utiliser lors de la création / édition.
crud/templates/members/edit.html
{% extends "base.html" %}
{% load bootstrap %}
{% block title %}Modification des membres{% endblock title %}
{% block content %}
{% if id %}
<h3 class="page-header">Modification des membres</h3>
<form action="{% url 'crud:edit' id=id %}" method="post" class="form-horizontal" role="form">
{% else %}
<h3 class="page-header">Inscription des membres</h3>
<form action="{% url 'crud:add' %}" method="post" class="form-horizontal" role="form">
{% endif %}
{% csrf_token %}
{{ form|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Envoyer</button>
</div>
</div>
</form>
<a href="{% url 'crud:index' %}" class="btn btn-default btn-sm">Revenir</a>
{% endblock content %}
Il peut être préférable de changer le titre par branchement conditionnel. Maintenant, veuillez vérifier le fonctionnement.
Enfin, nous implémenterons la fonction de suppression.
Je vais l'effacer pour le moment. Je suis vraiment en colère si je n'implémente pas le processus de suppression dans POST, mais c'est une autre fois.
crud/views.py
def delete(request, id):
# return HttpResponse("Effacer")
member = get_object_or_404(Member, pk=id)
member.delete()
return redirect('crud:index')
À tout le moins, vérifiez-le lors de la suppression. Ajoutez la description suivante à index.html. Il doit être juste avant {% endblock content%}.
members/index.html
{% block script %}
<script>
$(function(){
$("#btn_del").click(function(){
if(confirm("Voulez-vous le supprimer?")){
//Traitement oui (continuez sans rien faire)
}else{
//Annuler le traitement
return false;
}
});
})
</script>
{% endblock %}
C'est vraiment un bonus, mais implémentons un écran détaillé.
Comme pour l'édition et la suppression, il reçoit l'identifiant, recherche et transmet le résultat au modèle.
views.py
#Détails
def detail(request, id=id):
member = get_object_or_404(Member, pk=id)
return render(request, 'members/detail.html', {'member':member})
Développez le membre reçu. Je pense qu'il est préférable de construire une table, mais ce n'est pas le but, alors affichez-la pour le moment.
members/detail.html
{% extends "base.html" %}
{% load bootstrap %}
{% block title %}Détails du membre{% endblock title %}
{% block content %}
<h3>Informations détaillées des membres</h3>
<h5>Nom</h5>
{{ member.name }}
<h5>E-Mail</h5>
{{ member.email }}
<h5>âge</h5>
{{ member.age }}
<br>
<br>
<a href="{% url 'crud:index' %}" class="btn btn-default btn-sm">Revenir</a>
{% endblock content %}
Avec ce qui précède, j'ai essayé d'implémenter la fonction CRUD.
La pagination fait partie intégrante de toute application Web. En outre, chaque cadre fournit un moyen de le rendre plus facile. Dans Django, il semble qu'il soit courant d'utiliser LitView, alors utilisons-le. ListView est une sorte de vue à usage général basée sur une classe, et il semble être une classe View qui fournit des fonctions à usage général selon divers objectifs.
Vous pouvez réécrire la méthode d'index, mais à titre de comparaison, ajoutez la classe MemberList () sans changer la méthode d'index.
views.py
from django.views.generic import ListView #ajouter à
#liste
def index(request):
members = Member.objects.all().order_by('id') #Obtenez de la valeur
return render(request, 'members/index.html', {'members':members}) #Passer une valeur au modèle
#Liste (ajoutée pour la nation de la page)
class MemberList(ListView):
model = Member #Modèle à utiliser
context_object_name='members' #Paramètre de nom d'objet (la valeur par défaut est object_Ça devient une liste)
template_name='members/index.html' #Spécifier une page de modèle
paginate_by = 1 #Nombre de pages par page
Une fois ajouté, modifiez le routage pour utiliser MemberList () au lieu d'index sans pagination.
urls.py
from django.conf.urls import url
from crud import views
urlpatterns = [
#url(r'^members/$', views.index, name='index'), #Commenter
url(r'^members/$', views.MemberList.as_view(), name='index'), #ajouter à
url(r'^members/add/$', views.edit, name='add'),
url(r'^members/edit/(?P<id>\d+)/$', views.edit, name='edit'),
url(r'^members/delete/(?P<id>\d+)/$', views.delete, name='delete'),
]
À ce stade, vous ne devriez voir qu'une seule ligne. (Sans fonction avant / retour).
Écrivez des éléments HTML pour la pagination. De plus, ici, un élément de classe est ajouté afin que l'élément de pagination de Bootstrap puisse être rendu correctement.
Mettez le contenu suivant dans \ <! - Mettez la page ici-> dans index.html.
members/index.html
<!--Pagénation (ajouté ci-dessous)-->
{% if is_paginated %}
<ul class="pagination">
<!--Revenir<<Traitement d'affichage-->
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}">«</a></li>
{% else %}
<li class="disabled"><a href="#">«</a></li>
{% endif %}
<!--Affichage de la page (s'il y en a plusieurs, un traitement séparé est nécessaire) -->
{% for linkpage in page_obj.paginator.page_range %}
{% ifequal linkpage page_obj.number %}
<li class="active"><a href="#">{{ linkpage }}</a></li>
{% else %}
<li><a href="?page={{ linkpage }}">{{ linkpage }}</a></li>
{% endifequal %}
{% endfor %}
<!--prochain>>Traitement d'affichage-->
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}">»</a></li>
{% else %}
<li class="disabled"><a href="#">»</a></li>
{% endif %}
</ul>
{% endif %}
Ensuite, examinons brièvement la validation. Par défaut, la colonne définie dans le modèle? Il semble que la validation minimum (max_length etc.) soit définie en fonction des informations. En outre, il semble qu'une entrée de base soit requise.
Ce n'est pas suffisant, je vais donc l'ajouter. L'ajout semble perturber forms.py. Dans l'exemple ci-dessous
C'est comme ça.
crud/forms.py
from django.forms import ModelForm
from crud.models import Member
from django import forms
import re
class MemberForm(ModelForm):
#Remplacer les conditions définies dans le modèle? (Ecrire avant la description de Meta)
name = forms.CharField(required=False,max_length=8)
class Meta:
model = Member
fields = ('name','email','age',)
#Validation de chaque élément
def clean_email(self):
email = self.cleaned_data['email']
#Mais pour le moment
if re.match(r'.+@+',email) == None:
raise forms.ValidationError("Ce n'est pas une adresse e-mail.")
return email
Il semble que la validation de chaque élément puisse être ajoutée en définissant une méthode appelée clear_element name ().
La signification de> clear ~ semble signifier des données qui ont passé la validation de base (clear).
J'espère ajouter de telles choses bientôt. Pour le moment.
Recommended Posts