Tutoriel Python Django (8)

Ceci est un matériel pour les sessions d'étude. Dans ce tutoriel, une explication supplémentaire du modèle de Django et Je vais introduire une bibliothèque qui étend les fonctions de django et essayer diverses opérations sur le shell.

Autres tutoriels

Supplément de modèle

Il y avait une opinion que la relation entre le modèle, le champ et l'instance est difficile à comprendre, je vais donc la compléter.

Relation entre le code python et la base de données (tableau)

Le modèle représente une table DB. Il peut être modifié en définissant le nom de la table sur Meta, mais par défaut, il sera nommé ʻapp name_model name. Pour le modèle Question dans l'application polls, le nom de la table sera polls_question`.

Les modèles. ~ Le champ défini dans le modèle correspond aux colonnes du tableau. La colonne id est automatiquement ajoutée s'il n'y a pas de champ pour lequel PrimaryKey est défini.

Une instance de Model signifie un enregistrement sur la table DB.

polls/models.py


class Question(models.Model):
    class Meta:
        verbose_name = 'Question'
        verbose_name_plural = 'Forme multiple de question'
        ordering = ['-pub_date']

    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

Kobito.CVWNC3.png

Ceci et cela pour obtenir des enregistrements (instances)

Il est nécessaire d'émettre une instruction SQL pour obtenir un enregistrement d'une table sur la base de données. Pour ce faire, Model a une classe Manager. La classe QuerySet est responsable de l'émission et de la génération réelles de SQL et retourne l'instance de modèle de base après l'émission de SQL. Les opérations telles que l'acquisition et la création d'enregistrements sont effectuées via cette classe QuerySet. La classe Manager agit comme un relais entre Model et QuerySet, et est particulièrement étroitement liée à QuerySet.

Kobito.hB5eZg.png

QuerySet a également des méthodes comme «get» et «create» pour obtenir et créer des enregistrements de manière précise. Puisque l'itérateur est fourni, les enregistrements (= instances) à acquérir peuvent être acquis dans l'ordre en se tournant dans une boucle for.

qs = Question.objects.all()
for q in qs:
   #  q <---Ceci est l'enregistrement acquis et devient une instance de Question

Isolement de la méthode

Source → 8a9d88559ae94bea8bb706468eaa6459127c6f59

Puisque Model = table et instance = record, le traitement que vous voulez effectuer sur l'enregistrement est défini par la méthode d'instance. Inversement, le traitement que vous souhaitez effectuer sur la table elle-même est défini comme une méthode de classe.

Par exemple, le was_published_recently créé dans le tutoriel Il s'agit d'une méthode d'instance car il s'agit de «déterminer si l'enregistrement (= instance) a été publié récemment».

En dehors de cela, dans le cas de la méthode "Get published from Question table", faites-en une méthode de classe.

polls/models/py


class Question(models.Model):
...
    @classmethod
    def get_published_data(cls):
        return cls.objects.filter(pub_date__lte=timezone.now())

Dans le cas d'un filtre qui est "publié" comme indiqué dans l'exemple C'est un peu redondant, mais c'est aussi une bonne idée d'étendre le QuerySet.

polls/models.py(Extension QuerySet)


import datetime

from django.db import models
from django.utils import timezone


class QuestionQuerySet(models.query.QuerySet):
    def is_published(self):
        return self.filter(pub_date__lte=timezone.now())


class Question(models.Model):
...

    objects = models.Manager.from_queryset(QuestionQuerySet)()

...

    @classmethod
    def get_published_data(cls):
        return cls.objects.is_published()

Dans tous les cas Vous pouvez obtenir l'ensemble de requêtes publié en faisant Question.get_published_data ().

Cependant, lorsque Model est étendu directement, «pk est inférieur ou égal à 10 et a été publié». Vous ne pouvez pas mettre une condition au milieu.

Question.get_published_date().filter(pk__lte=10) Par exemple, si la condition est "publiée, pk est de 10 ou moins", elle sera appliquée.

Par contre, dans le cas de l'extension de QuerySet, vous pouvez appliquer un filtre pour obtenir les "publiés" où vous le souhaitez. Question.objects.filter(pk__lte=10).is_published()

Jouez avec Shell

Dans django, vous pouvez directement utiliser Model etc. en utilisant la commande manage.py shell. Je vais vous présenter une bibliothèque pour utiliser le shell un peu plus commodément.

Tout d'abord, ʻipython. Si vous le mettez, cela colorisera le shell et complétera les commandes. Ensuite, django-extensions`. Cela fournit diverses extensions à django comme son nom l'indique, pas seulement shell.

Les deux peuvent être facilement installés avec pip, veuillez donc les essayer. $ pip install ipython $ pip install django-extensions

Pour ipython, exécutez simplement $ ./manage.py shell et l'apparence changera automatiquement. django-extensions doit être ajouté à INSTALL_APPS dans les paramètres.

tutorial/settings.py


...
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',  #←←← Ajouter ceci
    'bootstrap3',
    'polls',
)
...

ʻS'il est réglé sur INSTALLED_APPS, la commande manage.py` sera capable d'exécuter des commandes pour django_extensions.

$ ./manage.py

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:
...
[django_extensions]
    admin_generator
    clean_pyc
    clear_cache
    compile_pyc
    create_app
    create_command
    create_jobs
    create_template_tags
    describe_form
    drop_test_database
    dumpscript
    export_emails
    find_template
    generate_secret_key
    graph_models
    mail_debug
    notes
    passwd
    pipchecker
    print_settings
    print_user_for_session
    reset_db
    runjob
    runjobs
    runprofileserver
    runscript
    runserver_plus
    set_default_site
    set_fake_emails
    set_fake_passwords
    shell_plus
    show_template_tags
    show_templatetags
    show_urls
    sqlcreate
    sqldiff
    sqldsn
    sync_s3
    syncdata
    unreferenced_files
    update_permissions
    validate_templates
...

Cette fois, nous utiliserons shell_plus, qui est une extension de la commande shell. En ajoutant l'option --print-sql au démarrage, vous pouvez également voir l'instruction SQL au moment de l'acquisition de l'instance, donc ajoutons-la.

$ ./manage.py shell_plus --print-sql
# Shell Plus Model Imports
from django.contrib.admin.models import LogEntry
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.models import Session
from polls.models import Choice, Question
# Shell Plus Django Imports
from django.db import transaction
from django.core.urlresolvers import reverse
from django.utils import timezone
from django.core.cache import cache
from django.db.models import Avg, Count, F, Max, Min, Sum, Q, Prefetch, Case, When
from django.conf import settings
Python 3.5.1 (default, Jan 23 2016, 02:16:23)
Type "copyright", "credits" or "license" for more information.

IPython 4.2.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]:

En shell, j'ai dû importer manuellement le modèle que je voulais utiliser, shell_plus chargera automatiquement le modèle lorsque vous le démarrerez.

Exécutons la commande get_published_data créée précédemment.

In [1]: Question.get_published_data()
Out[1]: SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date" FROM "polls_question" WHERE "polls_question"."pub_date" <= '2016-06-23 06:45:46.716854' ORDER BY "polls_question"."pub_date" DESC LIMIT 21

Execution time: 0.001740s [Database: default]

[<Question:Deuxième question>, <Question: what's up?>, <Question:Troisième question>]

In [2]:

Cette fois, l'option --print-sql est ajoutée, vous pouvez donc vérifier l'instruction SQL exécutée de cette manière.

Essayez d'enregistrer les données

Il existe deux façons d'enregistrer des données, l'une provient du gestionnaire (jeu de requêtes) et l'autre consiste à faire fonctionner directement l'instance.

Essayons d'abord de create. Puisqu'il est nécessaire de mettre la date dans pub_date, importez django.utils.timezone à l'avance et spécifiez la date et l'heure du jour dans pud_date.

In [3]: from django.utils import timezone

In [4]: Question.objects.create(pub_date=timezone.now())
BEGIN

Execution time: 0.000028s [Database: default]

INSERT INTO "polls_question" ("question_text", "pub_date") VALUES ('', '2016-06-23 07:02:01.013534')

Execution time: 0.000638s [Database: default]

Out[4]: <Question: >

Cela enregistrera un nouvel enregistrement dans la base de données.

In [5]: Question.objects.count()
SELECT COUNT(*) AS "__count" FROM "polls_question"

Execution time: 0.000154s [Database: default]

Out[5]: 4

Ensuite, essayons de créer à partir d'une instance. Dans le cas d'une instance, la simple création de celle-ci ne sera pas reflétée dans l'enregistrement DB. En exécutant save () de l'instance, si l'enregistrement existe, il sera mis à jour, et s'il n'existe pas, il sera inséré.

In [6]: ins = Question(pub_date=timezone.now(), question_text='Créer à partir de l'instance')

In [7]: ins
Out[7]: <Question:Créer à partir de l'instance>

In [8]: Question.objects.count()
SELECT COUNT(*) AS "__count" FROM "polls_question"

Execution time: 0.000177s [Database: default]

Out[8]: 4  #←←←←←←← Pas encore fait à ce stade.

In [9]: ins.save()  #←←←←←← Exécutez la méthode de mise à jour des enregistrements ici
BEGIN

Execution time: 0.000032s [Database: default]

INSERT INTO "polls_question" ("question_text", "pub_date") VALUES ('Créer à partir de l'instance', '2016-06-23 07:07:46.485479')

Execution time: 0.001240s [Database: default]


In [10]: Question.objects.count()
SELECT COUNT(*) AS "__count" FROM "polls_question"

Execution time: 0.000167s [Database: default]

Out[10]: 5  #←←←←←←← inséré

filtrer divers

Après avoir enregistré certaines données, essayons diverses choses en obtenant des enregistrements. Il existe plusieurs méthodes, mais pour le moment, il n'y a pas de problème si vous vous souvenez de filter et ʻexclude` pour affiner par conditions. Le filtre laissera des enregistrements qui correspondent aux conditions. Exclure est le contraire et les enregistrements qui ne correspondent pas aux conditions resteront.

Passez field name = condition comme argument du filtre. En ajoutant un caractère tel que «__lte» après le nom du champ, il ne s'agit pas d'une correspondance exacte et les conditions peuvent être modifiées comme suit. Veuillez vous référer au Document officiel pour connaître les conditions qui peuvent être utilisées.

OU rechercher

Document officiel

Enfin, la méthode de spécification de la condition OR est décrite. Étant donné que tous les filtres (exclure) sont AND, utilisez la classe Q pour effectuer une recherche OR pour les conditions. Q crée une instance avec nom de champ = condition de la même manière que celle spécifiée par le filtre. La recherche OU peut être réalisée en passant les conditions qui y sont créées au filtre de QuerySet. Pour Q, les symboles logiques & (et) | (ou) ~ (non) peuvent être utilisés.

In [12]: from django.db.models import Q

In [13]: q1 = Q(pk=1)

In [14]: q2 = Q(pk=2)

In [15]: Question.objects.filter(q1|q2)
Out[15]: SELECT "polls_question"."id", "polls_question"."question_text", "polls_question"."pub_date" FROM "polls_question" WHERE ("polls_question"."id" = 1 OR "polls_question"."id" = 2) ORDER BY "polls_question"."pub_date" DESC LIMIT 21

Execution time: 0.000390s [Database: default]

[<Question:Deuxième question>, <Question: what's up?>]

Le prochain tutoriel est indécis.

Autres tutoriels

Recommended Posts

Tutoriel Python Django (5)
Tutoriel Python Django (2)
Tutoriel Python Django (8)
Tutoriel Python Django (6)
Tutoriel Python Django (7)
Tutoriel Python Django (1)
Tutoriel du didacticiel Python Django
Tutoriel Python Django (3)
Tutoriel Python Django (4)
Résumé du didacticiel Python Django
Tutoriel Python
Fiche technique du didacticiel Python Django
Résumé du didacticiel Python
mémo du didacticiel django
Démarrer le didacticiel Django 1
Django 1.11 a démarré avec Python3.6
Tutoriel [Docker] (Python + php)
Framework Web Django Python
Didacticiel sur les associations polymorphes Django
tutoriel simple django oscar
Essayez Debian + Python 3.4 + django1.7 ……
Mémo du didacticiel Python OpenCV
[Tutoriel Python] Structure des données
Note du didacticiel Django Girls
Tutoriel Cloud Run (python)
Python Django CSS reflété
Faites Django avec CodeStar (Python3.6.8, Django2.2.9)
Lancez-vous avec Django! ~ Tutoriel ⑤ ~
Introduction à Python Django (2) Win
[Tutoriel Python] Outil de structure de contrôle
Python
Faites Django avec CodeStar (Python3.8, Django2.1.15)
Python3 + Django ~ Mac ~ avec Apache
Création de liste de tâches [Python Django]
Premiers pas avec Python Django (1)
Django
Premiers pas avec Python Django (4)
Premiers pas avec Python Django (3)
Lancez-vous avec Django! ~ Tutoriel ⑥ ~
Installez Python 3.7 et Django 3.0 (CentOS)
[Python] Tutoriel personnel sur l'arbre de décision
Histoire addictive GAE + python + Django
Introduction à Python Django (6)
Premiers pas avec Python Django (5)
Jusqu'à la sortie de Python [Django] de Web service [Tutorial Part 1]
8 commandes fréquemment utilisées dans Python Django
Créer une nouvelle application utiliser python, django
python + django + scikit-learn + mecab (1) avec heroku
python + django + scikit-learn + mecab (2) avec heroku
Exécutez python3 Django1.9 avec mod_wsgi (déployer)
Résumé du didacticiel Django Girls Première moitié
Trébucher lors du didacticiel django 1.7
Déployer le didacticiel Django sur IIS ①
Installer le framework Python django à l'aide de pip
Introduction à Python Django (2) Édition Mac
[Tutoriel Python] Une introduction facile à Python
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 5 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 4 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 1, 2, 3 ~
Historique d'apprentissage pour participer au développement d'applications d'équipe avec Python ~ Tutoriel Django 6 ~