Python Django Tutorial (8)

Dies ist ein Material für Lernsitzungen. In diesem Tutorial finden Sie eine ergänzende Erklärung zu Djangos Modell und Ich werde eine Bibliothek vorstellen, die die Funktionen von Django erweitert und verschiedene Operationen an der Shell ausprobiert.

Andere Tutorials

Modellergänzung

Es gab eine Meinung, dass die Beziehung zwischen Modell, Feld und Instanz schwer zu verstehen ist, deshalb werde ich sie ergänzen.

Beziehung zwischen Python-Code und DB (Tabelle)

Das Modell repräsentiert eine DB-Tabelle. Sie kann geändert werden, indem Sie den Tabellennamen auf Meta setzen. Standardmäßig heißt sie jedoch "app name_model name". Für das Fragenmodell in der Umfrage-App lautet der Tabellenname "polls_question".

Die im Modell definierten Modelle. ~ Feld entsprechen den Spalten in der Tabelle. Die ID-Spalte wird automatisch hinzugefügt, wenn kein Feld vorhanden ist, für das PrimaryKey festgelegt ist.

Eine Instanz von Model bedeutet einen Datensatz in der DB-Tabelle.

polls/models.py


class Question(models.Model):
    class Meta:
        verbose_name = 'Frage'
        verbose_name_plural = 'Multiple Form der Frage'
        ordering = ['-pub_date']

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

Kobito.CVWNC3.png

Dies und das zum Abrufen von Datensätzen (Instanzen)

Es ist erforderlich, eine SQL-Anweisung auszugeben, um einen Datensatz aus einer Tabelle in der Datenbank abzurufen. Zu diesem Zweck verfügt Model über eine Manager-Klasse. Die QuerySet-Klasse ist für die tatsächliche Ausgabe und Generierung von SQL verantwortlich und gibt die Basismodellinstanz nach der SQL-Ausgabe zurück. Vorgänge wie das Erfassen und Erstellen von Datensätzen werden über diese QuerySet-Klasse ausgeführt. Die Manager-Klasse fungiert als Relay zwischen Model und QuerySet und ist besonders eng mit QuerySet verwandt.

Kobito.hB5eZg.png

QuerySet verfügt auch über Methoden wie "get" und "create", um Datensätze genau abzurufen und zu erstellen. Da ein Iterator bereitgestellt wird, können die zu erfassenden Datensätze (= Instanzen) der Reihe nach erfasst werden, indem sie sich in eine for-Schleife drehen.

qs = Question.objects.all()
for q in qs:
   #  q <---Dies ist der erfasste Datensatz und wird zu einer Instanz der Frage

Isolierung der Methode

Quelle → 8a9d88559ae94bea8bb706468eaa6459127c6f59

Da Modell = Tabelle und Instanz = Datensatz, wird die Verarbeitung, die Sie für den Datensatz ausführen möchten, durch die Instanzmethode definiert. Umgekehrt ist die Verarbeitung, die Sie für die Tabelle selbst ausführen möchten, als Klassenmethode definiert.

Zum Beispiel das im Tutorial erstellte "was_published_recently" Es handelt sich um eine Instanzmethode, da "festgestellt wird, ob der Datensatz (= Instanz) kürzlich veröffentlicht wurde".

Abgesehen davon machen Sie die Methode "Von der Fragentabelle veröffentlichen" zu einer Klassenmethode.

polls/models/py


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

Im Fall eines Filters, der wie im Beispiel gezeigt "veröffentlicht" wird Es ist etwas redundant, aber es ist auch eine gute Idee, das QuerySet zu erweitern.

polls/models.py(QuerySet-Erweiterung)


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()

In beiden Fällen Sie können das veröffentlichte Abfrageset erhalten, indem Sie "Question.get_published_data ()" ausführen.

Wenn das Modell jedoch direkt erweitert wird, ist "pk 10 oder weniger und wurde veröffentlicht". Sie können keine Bedingung in die Mitte stellen.

Question.get_published_date().filter(pk__lte=10) Wenn die Bedingung "veröffentlicht, pk ist 10 oder weniger" lautet, wird sie angewendet.

Auf der anderen Seite können Sie bei der Erweiterung von QuerySet einen Filter anwenden, um "veröffentlichte" zu erhalten, wo immer Sie möchten. Question.objects.filter(pk__lte=10).is_published()

Spiel mit der Muschel

In Django können Sie Model usw. direkt bedienen, indem Sie mit dem Befehl manage.py shell arbeiten. Ich werde eine Bibliothek vorstellen, um die Shell etwas bequemer zu nutzen.

Zuallererst ipython. Wenn Sie dies eingeben, wird die Shell eingefärbt und die Befehle ergänzt. Als nächstes "Django-Erweiterungen". Dies bietet nicht nur Shell, sondern, wie der Name schon sagt, verschiedene Erweiterungen für Django.

Beide können einfach mit pip installiert werden, versuchen Sie es also bitte. $ pip install ipython $ pip install django-extensions

Führen Sie für ipython einfach $ ./manage.py shell aus und das Erscheinungsbild ändert sich automatisch. Django-Erweiterungen müssen in den Einstellungen zu INSTALL_APPS hinzugefügt werden.

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',  #←←← Fügen Sie dies hinzu
    'bootstrap3',
    'polls',
)
...

Bei der Einstellung "INSTALLED_APPS" kann der Befehl "manage.py" den Befehl für django_extensions ausführen.

$ ./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
...

Dieses Mal verwenden wir shell_plus, eine Erweiterung des Befehls shell. Durch Hinzufügen der Option "--print-sql" beim Start können Sie auch die SQL-Anweisung zum Zeitpunkt der Instanzerfassung anzeigen. Fügen Sie sie also hinzu.

$ ./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]:

In der Shell musste ich das Modell, das ich verwenden wollte, manuell importieren. shell_plus lädt das Modell automatisch, wenn Sie es starten.

Führen Sie den zuvor erstellten Befehl get_published_data aus.

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:Zweite Frage>, <Question: what's up?>, <Question:Dritte Frage>]

In [2]:

Dieses Mal wird die Option "--print-sql" hinzugefügt, damit Sie die auf diese Weise ausgeführte SQL-Anweisung überprüfen können.

Versuchen Sie, die Daten zu registrieren

Es gibt zwei Möglichkeiten, Daten zu registrieren: Die eine stammt vom Manager (Abfragesatz) und die andere besteht darin, die Instanz direkt zu betreiben.

Versuchen wir es zuerst mit "erstellen". Da das Datum in pub_date eingefügt werden muss, importieren Sie django.utils.timezone im Voraus und geben Sie das heutige Datum und die heutige Uhrzeit in pud_date an.

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: >

Dadurch wird ein neuer Datensatz in der Datenbank registriert.

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

Execution time: 0.000154s [Database: default]

Out[5]: 4

Als nächstes versuchen wir, aus einer Instanz zu erstellen. Wenn eine Instanz nur erstellt wird, wird sie nicht im DB-Datensatz angezeigt. Durch Ausführen von save () der Instanz wird der Datensatz aktualisiert, wenn er vorhanden ist, und wenn er nicht vorhanden ist, wird er eingefügt.

In [6]: ins = Question(pub_date=timezone.now(), question_text='Aus Instanz erstellen')

In [7]: ins
Out[7]: <Question:Aus Instanz erstellen>

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

Execution time: 0.000177s [Database: default]

Out[8]: 4  #←←←←←←← Noch nicht gemacht.

In [9]: ins.save()  #←←←←←← Führen Sie hier die Datensatzaktualisierungsmethode aus
BEGIN

Execution time: 0.000032s [Database: default]

INSERT INTO "polls_question" ("question_text", "pub_date") VALUES ('Aus Instanz erstellen', '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  #←←←←←←← eingefügt

Filter verschiedene

Nachdem Sie einige Daten registriert haben, versuchen wir verschiedene Dinge, indem wir Datensätze abrufen. Es gibt verschiedene Methoden, aber vorerst gibt es kein Problem, wenn Sie sich an "Filter" und "Ausschluss" erinnern, um die Bedingungen einzugrenzen. Der Filter hinterlässt Datensätze, die den Bedingungen entsprechen. Ausschließen ist das Gegenteil, und Datensätze, die nicht den Bedingungen entsprechen, bleiben erhalten.

Übergeben Sie "Feldname = Bedingung" als Argument des Filters. Wenn Sie nach dem Feldnamen ein Zeichen wie "__lte" einfügen, ist dies keine exakte Übereinstimmung, und die Bedingungen können wie folgt geändert werden. Informationen zu den Bedingungen, die verwendet werden können, finden Sie unter Offizielles Dokument.

ODER suchen

Offizielle Dokumente

Schließlich wird das Verfahren zum Spezifizieren der ODER-Bedingung beschrieben. Da alle Filter (ausschließen) UND sind, verwenden Sie die Q-Klasse, um eine ODER-Suche nach Bedingungen durchzuführen. Q erstellt eine Instanz mit "Feldname = Bedingung" auf die gleiche Weise wie vom Filter angegeben. Die ODER-Suche kann realisiert werden, indem die dort erstellten Bedingungen an den Filter von QuerySet übergeben werden. Für Q können die logischen Symbole "&" (und) "|" (oder) "~" (nicht) verwendet werden.

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:Zweite Frage>, <Question: what's up?>]

Das nächste Tutorial ist unentschlossen.

Andere Tutorials

Recommended Posts

Python Django Tutorial (5)
Python Django Tutorial (2)
Python Django Tutorial (8)
Python Django Tutorial (6)
Python Django Tutorial (7)
Python Django Tutorial (1)
Python Django Tutorial Tutorial
Python Django Tutorial (3)
Python Django Tutorial (4)
Zusammenfassung des Python Django-Tutorials
Python-Tutorial
Python Django Tutorial Cheet Sheet
Zusammenfassung des Python-Tutorials
Django Tutorial Memo
Starten Sie das Django Tutorial 1
Django 1.11 wurde mit Python3.6 gestartet
[Docker] Tutorial (Python + PHP)
Django Python Web Framework
Django Polymorphic Associations Tutorial
Django Oscar einfaches Tutorial
Versuchen Sie Debian + Python 3.4 + django1.7 ……
Python OpenCV Tutorial Memo
[Python-Tutorial] Datenstruktur
Django Girls Tutorial Hinweis
Cloud Run Tutorial (Python)
Python Django CSS reflektiert
Mach Django mit CodeStar (Python3.6.8, Django2.2.9)
Fangen Sie mit Django an! ~ Tutorial ⑤ ~
Einführung in Python Django (2) Win
[Python-Tutorial] Kontrollstruktur-Tool
Python
Mach Django mit CodeStar (Python3.8, Django2.1.15)
Python3 + Django ~ Mac ~ mit Apache
ToDo-Listenerstellung [Python Django]
Erste Schritte mit Python Django (1)
Django
Erste Schritte mit Python Django (4)
Erste Schritte mit Python Django (3)
Fangen Sie mit Django an! ~ Tutorial ⑥ ~
Installieren Sie Python 3.7 und Django 3.0 (CentOS)
[Python] Persönliches Tutorial zum Entscheidungsbaum
GAE + Python + Django süchtig machende Geschichte
Einführung in Python Django (6)
Erste Schritte mit Python Django (5)
Bis zur Veröffentlichung von Python [Django] de Web Service [Tutorial Teil 1]
8 häufig verwendete Befehle in Python Django
Erstellen Sie eine neue Anwendung mit Python, Django
Python + Django + Scikit-Learn + Mecab (1) mit Heroku
Python + Django + Scikit-Learn + Mecab (2) mit Heroku
Führen Sie python3 Django1.9 mit mod_wsgi aus (deploy)
Django Girls Tutorial Zusammenfassung Erste Hälfte
Stolpern Sie beim Django 1.7-Tutorial
Stellen Sie das Django-Lernprogramm für IIS bereit ①
Installieren Sie das Python Framework Django mit pip
Einführung in Python Django (2) Mac Edition
[Python Tutorial] Eine einfache Einführung in Python
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 5 ~
Lernverlauf für die Teilnahme an der Entwicklung von Team-Apps mit Python ~ Django Tutorial 4 ~
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 1, 2, 3 ~
Lernverlauf für die Teilnahme an der Team-App-Entwicklung mit Python ~ Django Tutorial 6 ~