Einführung
Im vorherigen Tutorial, “ Wie man eine Django-App erstellt und mit einer Datenbank verbindet „, haben wir erklärt, wie man eine MySQL-Datenbank erstellt, wie man eine Django-Anwendung erstellt und startet, und wie man sie mit einer MySQL-Datenbank verbindet.
In diesem Tutorial werden wir die Django-Modelle erstellen, die die Felder und Verhaltensweisen der im Blog-Anwendungsdaten gespeicherten Daten definieren. Diese Modelle ordnen die Daten Ihrer Django-Anwendung der Datenbank zu. Es ist das, was Django verwendet, um die Datenbanktabellen über ihre objektrelationalen Abbildungs (ORM)-API zu generieren, die als „Modelle“ bezeichnet wird.
Voraussetzungen
Dieses Tutorial ist Teil der Django-Entwicklungsreihe und setzt diese fort.
Wenn Sie dieser Reihe nicht gefolgt sind, gehen wir von folgendem aus:
- Sie haben Django-Version 4 oder höher installiert.
- Sie haben Ihre Django-App mit einer Datenbank verbunden. Wir verwenden MySQL, und Sie können diese Verbindung herstellen, indem Sie Teil zwei der Django-Serie „Wie man eine Django-App erstellt und mit einer Datenbank verbindet“ befolgen.
- Sie arbeiten mit einem Unix-basierten Betriebssystem, vorzugsweise einem Ubuntu 22.04-Cloud-Server, da dies das System ist, auf dem wir getestet haben. Wenn Sie Django in einer ähnlichen Umgebung einrichten möchten, verweisen wir auf unser Tutorial „Wie man Django installiert und eine Entwicklungsumgebung auf Ubuntu 22.04 einrichtet“.
Da dieses Tutorial größtenteils mit Django-Modellen umgeht, können Sie möglicherweise auch dann folgen, wenn Sie eine etwas andere Konfiguration haben.
Schritt 1 – Django-Anwendung erstellen
Um der Django-Philosophie der Modularität gerecht zu werden, werden wir eine Django-App innerhalb unseres Projekts erstellen, die alle Dateien enthält, die für die Erstellung der Blog-Website erforderlich sind.
Immer wenn wir in Python und Django arbeiten, sollten wir unsere Python-Virtualenv aktivieren und in das Stammverzeichnis unserer App wechseln. Wenn Sie den Anweisungen in der Serie gefolgt sind, können Sie dies erreichen, indem Sie Folgendes eingeben.
- cd ~/my_blog_app
- . env/bin/activate
- cd blog
Von dort aus führen wir diesen Befehl aus:
- python manage.py startapp blogsite
Das wird unsere App zusammen mit einem blogsite
Verzeichnis erstellen.
Zu diesem Zeitpunkt in der Tutorial-Reihe haben Sie die folgende Verzeichnisstruktur für Ihr Projekt:
my_blog_app/
└── blog
├── blog
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-38.pyc
│ │ ├── settings.cpython-38.pyc
│ │ ├── urls.cpython-38.pyc
│ │ └── wsgi.cpython-38.pyc
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── blogsite
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py
Die Datei, auf die wir uns in diesem Tutorial konzentrieren werden, ist die models.py
Datei, die sich im blogsite
Verzeichnis befindet.
Schritt 2 — Fügen Sie das Posts-Modell hinzu
Zuerst müssen wir die models.py
Datei öffnen und bearbeiten, damit sie den Code zur Erzeugung eines Post
Modells enthält. Ein Post
Modell enthält die folgenden Datenbankfelder:
title
— Der Titel des Blogposts.slug
— Wo gültige URLs für Webseiten gespeichert und generiert werden.content
— Der textuelle Inhalt des Blogposts.created_on
— Das Datum, an dem der Beitrag erstellt wurde.author
— Die Person, die den Beitrag verfasst hat.
Wechseln Sie nun in das Verzeichnis, in dem sich die models.py
Datei befindet.
- cd ~/my_blog_app/blog/blogsite
Verwenden Sie das cat
Kommando, um den Inhalt der Datei in Ihrem Terminal anzuzeigen.
- cat models.py
Die Datei sollte den folgenden Code enthalten, der Modelle importiert, zusammen mit einem Kommentar, der beschreibt, was in diese models.py
Datei eingefügt werden soll.
from django.db import models
# Erstellen Sie hier Ihre Modelle.
Verwenden Sie Ihren bevorzugten Texteditor und fügen Sie den folgenden Code zur Datei models.py
hinzu. Wir verwenden nano
als Texteditor, aber Sie können gerne Ihren bevorzugten Editor verwenden.
- nano models.py
Innerhalb dieser Datei ist bereits der Code zum Importieren der Models-API hinzugefügt. Wir können den anschließenden Kommentar löschen. Dann importieren wir slugify
zum Generieren von Slugs aus Strings, Djangos User
für die Authentifizierung und reverse
aus django.urls
, um uns mehr Flexibilität bei der Erstellung von URLs zu geben.
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
Als nächstes fügen wir die Klassenmethode auf der Modelklasse hinzu, die wir Post
nennen werden, mit den folgenden Datenbankfeldern: title
, slug
, content
, created_on
und author
. Fügen Sie diese unter Ihre Importanweisungen ein.
...
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()
Dann werden wir Funktionalität für die Generierung der URL und die Funktion zum Speichern des Beitrags hinzufügen. Dies ist wichtig, da dies einen eindeutigen Link erstellt, um unseren einzigartigen Beitrag abzustimmen.
...
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
Jetzt müssen wir dem Modell mitteilen, wie die Beiträge geordnet und auf der Webseite angezeigt werden sollen. Die Logik dafür wird zu einer verschachtelten inneren Meta
-Klasse hinzugefügt. Die Meta
-Klasse enthält im Allgemeinen andere wichtige Modelllogik, die nicht mit der Definition von Datenbankfeldern zusammenhängt.
...
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
Zum Schluss fügen wir das Comment
-Modell zu dieser Datei hinzu. Dies umfasst das Hinzufügen einer weiteren Klasse mit dem Namen Comment
, die models.Models
in ihrer Signatur enthält, und die folgenden Datenbankfelder definiert:
name
— Der Name der Person, die den Kommentar veröffentlicht.Email
— Die E-Mail-Adresse der Person, die den Kommentar veröffentlicht hat.Text
— Der Text des Kommentars selbst.Beitrag
— Der Beitrag, zu dem der Kommentar erstellt wurde.Erstellt_am
— Die Zeit, zu der der Kommentar erstellt wurde.
...
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
An diesem Punkt wird models.py
vollständig sein. Stellen Sie sicher, dass Ihre models.py
-Datei folgendermaßen aussieht:
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True, max_length=255)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
author = models.TextField()
def get_absolute_url(self):
return reverse('blog_post_detail', args=[self.slug])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
class Comment(models.Model):
name = models.CharField(max_length=42)
email = models.EmailField(max_length=75)
website = models.URLField(max_length=200, null=True, blank=True)
content = models.TextField()
post = models.ForeignKey(Post, on_delete=models.CASCADE)
created_on = models.DateTimeField(auto_now_add=True)
Speichern Sie die Datei und schließen Sie sie. Wenn Sie nano verwenden, können Sie dies tun, indem Sie CTRL
und X
eingeben, dann Y
, dann ENTER
.
Mit der eingerichteten models.py
-Datei können wir nun unsere settings.py
-Datei aktualisieren.
Schritt 3 — Einstellungen aktualisieren
Da wir Modelle zu unserer Anwendung hinzugefügt haben, müssen wir unser Projekt darüber informieren, dass die blogsite
-App, die wir gerade hinzugefügt haben, existiert. Dies tun wir, indem wir sie dem Abschnitt INSTALLED_APPS
in der settings.py
-Datei hinzufügen.
Navigieren Sie zum Verzeichnis, in dem Ihre settings.py
-Datei liegt.
- cd ~/my_blog_app/blog/blog
Öffnen Sie von hier aus Ihre settings.py
-Datei, beispielsweise mit nano.
- nano settings.py
Fügen Sie die blogsite
-App mit geöffneter Datei dem Abschnitt INSTALLED_APPS
der Datei wie unten angegeben hinzu.
# Anwendungsdefinition
INSTALLED_APPS = [
'blogsite',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Mit der blogsite
-App hinzugefügt, können Sie die Datei speichern und schließen.
An diesem Punkt sind wir bereit, diese Änderungen anzuwenden.
Schritt 4 – Migrationen erstellen
Mit unseren Modellen Post
und Comment
hinzugefügt, ist der nächste Schritt, diese Änderungen anzuwenden, damit unser MySQL
-Datenbankschema sie erkennt und die notwendigen Tabellen erstellt.
Zuerst müssen wir unsere Modelländerungen in einzelne Migrationsdateien verpacken, indem wir den Befehl makemigrations
verwenden. Diese Dateien sind ähnlich wie Commits
in einem Versionskontrollsystem wie Git.
Wenn Sie nun zu ~/my_blog_app/blog/blogsite/migrations
navigieren und ls
ausführen, werden Sie feststellen, dass nur eine __init__.py
-Datei vorhanden ist. Dies wird sich ändern, sobald wir die Migrationen hinzufügen.
Wechseln Sie zum Blog-Verzeichnis mit cd
, wie folgt:
- cd ~/my_blog_app/blog
Dann führen Sie den Befehl makemigrations
auf manage.py
aus.
- python manage.py makemigrations
Sie sollten dann folgende Ausgabe in Ihrem Terminalfenster erhalten:
OutputMigrations for 'blogsite':
blogsite/migrations/0001_initial.py
- Create model Post
- Create model Comment
Erinnern Sie sich, als wir zu /~/my_blog_app/blog/blogsite/migrations
navigiert sind und dort nur die Datei __init__.py
vorhanden war? Wenn wir jetzt in dieses Verzeichnis zurückkehren (cd
), werden wir feststellen, dass zwei Elemente hinzugefügt wurden: __pycache__
und 0001_initial.py
. Die Datei 0001_initial.py
wurde automatisch generiert, als Sie makemigrations
ausgeführt haben. Eine ähnliche Datei wird jedes Mal generiert, wenn Sie makemigrations
ausführen.
Führen Sie den Befehl less 0001_initial.py
im Verzeichnis aus, wenn Sie den Inhalt der Datei lesen möchten.
Navigieren Sie jetzt zu ~/my_blog_app/blog
:
- cd ~/my_blog_app/blog
Da wir eine Migrationsdatei erstellt haben, müssen wir die Änderungen, die diese Dateien beschreiben, mit dem Befehl migrate
auf die Datenbank anwenden. Aber zuerst schauen wir uns an, welche Migrationen bereits existieren, indem wir den Befehl showmigrations
verwenden.
- python manage.py showmigrations
Outputadmin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
blogsite
[ ] 0001_initial
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
Sie werden feststellen, dass alle Migrationen überprüft sind, außer derjenigen für 0001_initial
, die wir gerade mit den Modellen Post
und Comment
erstellt haben.
Jetzt schauen wir uns an, welche SQL
-Anweisungen ausgeführt werden, wenn wir die Migrationen durchführen, mit dem folgenden Befehl. Er nimmt die Migration und den Titel der Migration als Argument an:
- python manage.py sqlmigrate blogsite 0001_initial
Nachfolgend wird die tatsächliche SQL-Abfrage angezeigt, die im Hintergrund ausgeführt wird.
Output--
-- Erstelle Modell Post
--
CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL);
--
-- Erstelle Modell Comment
--
CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL);
ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);
Führen wir nun die Migrationen durch, damit sie auf unsere MySQL-Datenbank angewendet werden.
- python manage.py migrate
Wir erhalten die folgende Ausgabe:
OutputOperations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
Applying blogsite.0001_initial... OK
Sie haben Ihre Migrationen erfolgreich angewendet.
Es ist wichtig zu beachten, dass es drei Einschränkungen bei Django-Migrationen mit MySQL als Backend gibt, wie in der Django-Dokumentation angegeben.
- Fehlende Unterstützung für Transaktionen bei Schema-Änderungsvorgängen. Mit anderen Worten, wenn eine Migration nicht erfolgreich angewendet wird, müssen Sie die Änderungen manuell rückgängig machen, um eine weitere Migration zu versuchen. Es ist nicht möglich, zu einem früheren Zeitpunkt zurückzukehren, bevor Änderungen in der fehlgeschlagenen Migration vorgenommen wurden.
- Für die meisten Schema-Änderungsvorgänge wird MySQL Tabellen vollständig neu schreiben. Im schlimmsten Fall ist die Zeitkomplexität proportional zur Anzahl der Zeilen in der Tabelle, um Spalten hinzuzufügen oder zu entfernen. Laut Django-Dokumentation könnte dies so langsam sein wie eine Minute pro Million Zeilen.
- In MySQL gibt es kleine Grenzen für die Namenlängen von Spalten, Tabellen und Indizes. Es gibt auch eine Grenze für die kombinierte Größe aller Spalten und Indexabdeckungen. Während einige andere Backends höhere Grenzen unterstützen können, die in Django erstellt wurden, können dieselben Indizes nicht mit einem MySQL-Backend erstellt werden.
Für jede Datenbank, die Sie für die Verwendung mit Django in Betracht ziehen, sollten Sie die Vor- und Nachteile jeder einzelnen abwägen.
Schritt 5 — Überprüfen des Datenbankschemas
Mit abgeschlossenen Migrationen sollten wir die erfolgreiche Generierung der MySQL-Tabellen überprüfen, die wir über unsere Django-Modelle erstellt haben.
Um dies zu tun, führen Sie den folgenden Befehl im Terminal aus, um sich bei MySQL anzumelden. Wir verwenden den djangouser
, den wir im vorherigen Tutorial erstellt haben.
- mysql blog_data -u djangouser
Wählen Sie jetzt unsere Datenbank blog_data
aus. Wenn Sie nicht wissen, welche Datenbank Sie verwenden, können Sie alle Datenbanken mit SHOW DATABASES;
in SQL anzeigen.
- USE blog_data;
Dann geben Sie den folgenden Befehl ein, um die Tabellen anzuzeigen.
- SHOW TABLES;
Diese SQL-Abfrage sollte Folgendes offenbaren:
Output+----------------------------+
| Tables_in_blog_data |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| blogsite_comment |
| blogsite_post |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
12 rows in set (0.01 sec)
Zu den Tabellen gehören blogsite_comment
und blogsite_post
. Dies sind die Modelle, die wir gerade erstellt haben. Überprüfen wir, ob sie die von uns definierten Felder enthalten.
- DESCRIBE blogsite_comment;
Output+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(42) | NO | | NULL | |
| email | varchar(75) | NO | | NULL | |
| website | varchar(200) | YES | | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| post_id | int | NO | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
- DESCRIBE blogsite_post;
Output+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| title | varchar(255) | NO | | NULL | |
| slug | varchar(255) | NO | UNI | NULL | |
| content | longtext | NO | | NULL | |
| created_on | datetime(6) | NO | | NULL | |
| author | longtext | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
Wir haben überprüft, dass die Datenbanktabellen erfolgreich aus unseren Django-Modellmigrationen generiert wurden.
Sie können MySQL mit CTRL
+ D
schließen, und wenn Sie bereit sind, Ihre Python-Umgebung zu verlassen, können Sie den Befehl deactivate
ausführen:
- deactivate
Wenn Sie Ihre Programmierumgebung deaktivieren, gelangen Sie zurück zur Terminal-Befehlsaufforderung.
Fazit
{
„error“: „Upstream error…“
}
Source:
https://www.digitalocean.com/community/tutorials/how-to-create-django-models