Introductie
In de vorige handleiding, “Hoe je een Django-app maakt en ermee verbindt met een database,” hebben we behandeld hoe je een MySQL-database maakt, hoe je een Django-applicatie maakt en start, en hoe je deze verbindt met een MySQL-database.
In deze handleiding zullen we de Django modellen maken die de velden en gedragingen van de gegevens van de Blog-toepassing definiëren die we zullen opslaan. Deze modellen mappen de gegevens van je Django-toepassing naar de database. Het is wat Django gebruikt om de databasetabellen te genereren via hun object-relationele mapping (ORM) API, ook wel “modellen” genoemd.
Vereisten
Deze handleiding maakt deel uit van de Django-ontwikkelingsserie en is een voortzetting van die serie.
Als je niet hebt meegedaan met deze serie, gaan we uit van het volgende:
- Je hebt Django-versie 4 of hoger geïnstalleerd.
- Je hebt je Django-applicatie verbonden met een database. We gebruiken MySQL, en je kunt deze verbinding tot stand brengen door deel twee van de Django-serie te volgen, “Hoe je een Django-app maakt en eraan verbindt met een database.”
- Je werkt met een op Unix gebaseerd besturingssysteem, bij voorkeur een Ubuntu 22.04-cloudserver, aangezien dit het systeem is waarop we hebben getest. Als je Django op een vergelijkbare omgeving wilt instellen, raadpleeg dan onze handleiding, “Hoe je Django installeert en een ontwikkelingsomgeving opzet op Ubuntu 22.04.”
Omdat deze handleiding voornamelijk betrekking heeft op Django-modellen, kun je waarschijnlijk meekomen, zelfs als je een enigszins andere opstelling hebt.
Stap 1 — Maak Django-applicatie
Om consistent te zijn met de modulaire filosofie van Django, zullen we een Django-applicatie binnen ons project maken die alle bestanden bevat die nodig zijn voor het maken van de blogwebsite.
Telkens wanneer we aan het werk gaan in Python en Django, moeten we onze Python virtuele omgeving activeren en naar de hoofdmap van onze app gaan. Als je de serie hebt gevolgd, kun je dit doen door het volgende in te typen.
- cd ~/my_blog_app
- . env/bin/activate
- cd blog
Vanaf daar laten we deze opdracht uitvoeren:
- python manage.py startapp blogsite
Dit zal onze app samen met een blogsite
map creëren.
Op dit punt in de tutorialserie, heb je de volgende mappenstructuur voor je project:
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
Het bestand waarop we ons in deze tutorial zullen richten, is het models.py
-bestand, dat zich in de blogsite
-map bevindt.
Stap 2 — Voeg het Post-model toe
Eerst moeten we het models.py
-bestand openen en bewerken zodat het de code bevat voor het genereren van een Post
-model. Een Post
-model bevat de volgende databasevelden:
title
— De titel van de blogpost.slug
— Waar geldige URL’s worden opgeslagen en gegenereerd voor webpagina’s.content
— De tekstuele inhoud van de blogpost.created_on
— De datum waarop de post is gemaakt.author
— De persoon die de post heeft geschreven.
Ga nu naar de map waar het models.py
-bestand zich bevindt.
- cd ~/my_blog_app/blog/blogsite
Gebruik het cat
-commando om de inhoud van het bestand in je terminal te tonen.
- cat models.py
Het bestand moet de volgende code bevatten, die modellen importeert, samen met een opmerking die beschrijft wat in dit models.py
-bestand moet worden geplaatst.
from django.db import models
# Maak hier je modellen aan.
Gebruik uw favoriete teksteditor en voeg de volgende code toe aan het `models.py` bestand. We zullen `nano` gebruiken als onze teksteditor, maar u bent vrij om te gebruiken wat u maar wilt.
- nano models.py
Binnen dit bestand is de code om de models API te importeren al toegevoegd, we kunnen nu de bijbehorende opmerking verwijderen. Vervolgens zullen we `slugify` importeren voor het genereren van slugs van strings, Django’s `User` voor authenticatie, en `reverse` van `django.urls` om ons meer flexibiliteit te geven bij het maken van URL’s.
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
Vervolgens voegen we de klassenmethode toe aan de modelklasse die we `Post` zullen noemen, met de volgende databasevelden: `title`, `slug`, `content`, `created_on` en `author`. Voeg deze toe onder uw importverklaringen.
...
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()
Hierna zullen we functionaliteit toevoegen voor het genereren van de URL en de functie voor het opslaan van het bericht. Dit is cruciaal, omdat dit een unieke link creëert die overeenkomt met ons unieke bericht.
...
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)
Nu moeten we het model vertellen hoe de berichten moeten worden gesorteerd en weergegeven op de webpagina. De logica hiervoor wordt toegevoegd aan een geneste binnenste `Meta`-klasse. De `Meta`-klasse bevat over het algemeen andere belangrijke modellogica die niet gerelateerd is aan de definitie van databasevelden.
...
class Meta:
ordering = ['created_on']
def __unicode__(self):
return self.title
Tenslotte zullen we het `Comment`-model aan dit bestand toevoegen. Dit houdt in dat we een andere klasse toevoegen met de naam `Comment` met `models.Models` in de handtekening en de volgende databasevelden gedefinieerd:
name
— De naam van de persoon die de opmerking plaatst.email
— Het e-mailadres van de persoon die de reactie plaatst.text
— De tekst van de reactie zelf.post
— Het bericht waarop de reactie is geplaatst.created_on
— Het tijdstip waarop de reactie is aangemaakt.
...
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)
Op dit punt zal models.py
compleet zijn. Zorg ervoor dat je models.py
bestand overeenkomt met het volgende:
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)
Zorg ervoor dat je het bestand opslaat en sluit. Als je nano gebruikt, kun je dit doen door CTRL
en X
te typen, vervolgens Y
, en dan ENTER
.
Met het models.py
bestand opgezet, kunnen we doorgaan met het bijwerken van ons settings.py
bestand.
Stap 3 — Instellingen bijwerken
Nu we modellen aan onze applicatie hebben toegevoegd, moeten we ons project op de hoogte stellen van het bestaan van de zojuist toegevoegde blogsite
app. Dit doen we door het toe te voegen aan de INSTALLED_APPS
sectie in settings.py
.
Navigeer naar de directory waar je settings.py
staat.
- cd ~/my_blog_app/blog/blog
Vanaf hier, open je settings.py
bestand, bijvoorbeeld met nano.
- nano settings.py
Met het bestand geopend, voeg je jouw blogsite
app toe aan de INSTALLED_APPS
sectie van het bestand, zoals hieronder aangegeven.
# Applicatie definitie
INSTALLED_APPS = [
'blogsite',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Met de toegevoegde blogsite
-applicatie kunt u het bestand opslaan en afsluiten.
Op dit punt zijn we klaar om door te gaan met het toepassen van deze wijzigingen.
Stap 4 – Migraties maken
Met onze modellen Post
en Comment
toegevoegd, is de volgende stap om deze wijzigingen toe te passen, zodat ons MySQL
-databaseschema ze herkent en de noodzakelijke tabellen maakt.
Eerst moeten we onze modelwijzigingen verpakken in afzonderlijke migratiebestanden met het commando makemigrations
. Deze bestanden lijken op commits
in een versiebeheersysteem zoals Git.
Nu, als je naar ~/my_blog_app/blog/blogsite/migrations
gaat en ls
uitvoert, zul je merken dat er alleen een __init__.py
-bestand is. Dit zal veranderen zodra we de migraties toevoegen.
Verander naar de blog-directory met cd
, zoals dit:
- cd ~/my_blog_app/blog
Voer vervolgens het makemigrations
-commando uit op manage.py
.
- python manage.py makemigrations
Je zou dan de volgende uitvoer in je terminalvenster moeten ontvangen:
OutputMigrations for 'blogsite':
blogsite/migrations/0001_initial.py
- Create model Post
- Create model Comment
Herinner je nog toen we naar /~/my_blog_app/blog/blogsite/migrations
navigeerden en het alleen het __init__.py
-bestand had? Als we nu terug gaan naar die map, zullen we merken dat er twee items zijn toegevoegd: __pycache__
en 0001_initial.py
. Het bestand 0001_initial.py
is automatisch gegenereerd toen je makemigrations
uitvoerde. Een vergelijkbaar bestand wordt gegenereerd telkens wanneer je makemigrations
uitvoert.
Voer less 0001_initial.py
uit vanuit de map waarin het zich bevindt als je de inhoud van het bestand wilt lezen.
Navigeer nu naar ~/my_blog_app/blog
:
- cd ~/my_blog_app/blog
Aangezien we een migratiebestand hebben gemaakt, moeten we de wijzigingen die deze bestanden beschrijven toepassen op de database met behulp van het commando migrate
. Maar laten we eerst controleren welke migraties momenteel bestaan met het showmigrations
-commando.
- 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
Je zult merken dat alle migraties zijn gecontroleerd, behalve die voor 0001_initial
die we zojuist hebben aangemaakt met de modellen Post
en Comment
.
Laten we nu controleren welke SQL
-statements worden uitgevoerd zodra we de migraties maken, met behulp van het volgende commando. Het accepteert de migratie en de titel van de migratie als argument:
- python manage.py sqlmigrate blogsite 0001_initial
Hieronder wordt de daadwerkelijke SQL-query onthuld die achter de schermen wordt uitgevoerd.
Output--
-- Maak model 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);
--
-- Maak model 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`);
Laten we nu de migraties uitvoeren zodat ze worden toegepast op onze MySQL-database.
- python manage.py migrate
We zullen de volgende uitvoer ontvangen:
OutputOperations to perform:
Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
Applying blogsite.0001_initial... OK
Je hebt nu succesvol je migraties toegepast.
Het is belangrijk om in gedachten te houden dat er drie kanttekeningen zijn bij Django-migraties met MySQL als jouw backend, zoals vermeld in de Django-documentatie.
- Gebrek aan ondersteuning voor transacties rondom schemawijzigingsoperaties. Met andere woorden, als een migratie niet succesvol kan worden toegepast, moet je handmatig de wijzigingen ongedaan maken die je hebt aangebracht om een andere migratie te proberen. Het is niet mogelijk om terug te rollen naar een eerder punt, voordat er wijzigingen zijn aangebracht in de mislukte migratie.
- Voor de meeste schemawijzigingsoperaties zal MySQL tabellen volledig herschrijven. In het ergste geval zal de tijdscomplexiteit evenredig zijn met het aantal rijen in de tabel om kolommen toe te voegen of te verwijderen. Volgens de Django-documentatie kan dit zo langzaam zijn als één minuut per miljoen rijen.
- In MySQL zijn er kleine limieten aan de lengte van namen voor kolommen, tabellen en indices. Er is ook een limiet aan de gecombineerde grootte van alle kolommen en indexomslagen. Terwijl sommige andere back-ends hogere limieten kunnen ondersteunen die zijn gemaakt in Django, zullen dezelfde indices niet kunnen worden aangemaakt met een MySQL-backend.
Voor elke database die je overweegt te gebruiken met Django, zorg ervoor dat je de voor- en nadelen van elk afweegt.
Stap 5 — Verifieer Database Schema
Met de migraties voltooid, moeten we de succesvolle generatie van de MySQL-tabellen verifiëren die we hebben aangemaakt via onze Django-modellen.
Om dit te doen, voer de volgende opdracht uit in de terminal om in te loggen op MySQL. We zullen de djangogebruiker
gebruiken die we hebben aangemaakt in de vorige tutorial.
- mysql blog_data -u djangouser
Selecteer nu onze database blog_data
. Als je niet weet welke database je gebruikt, kun je alle databases tonen met SHOW DATABASES;
in SQL.
- USE blog_data;
Typ vervolgens de volgende opdracht om de tabellen te bekijken.
- SHOW TABLES;
Deze SQL-query zou het volgende moeten onthullen:
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)
Onder de tabellen bevinden zich blogsite_comment
en blogsite_post
. Dit zijn de modellen die we zojuist hebben gemaakt. Laten we controleren of ze de door ons gedefinieerde velden bevatten.
- 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)
We hebben geverifieerd dat de databasetabellen succesvol zijn gegenereerd vanuit onze Django-modelmigraties.
Je kunt MySQL afsluiten met CTRL
+ D
en wanneer je klaar bent om je Python-omgeving te verlaten, kun je de deactivate
-opdracht uitvoeren:
- deactivate
Het deactiveren van je programmeeromgeving brengt je terug naar de terminal-opdrachtprompt.
Conclusie
In deze tutorial hebben we met succes modellen toegevoegd voor basisfunctionaliteiten in een blog webapplicatie. Je hebt geleerd hoe je modellen
moet coderen, hoe migraties
werken en het proces om Django modellen
te vertalen naar daadwerkelijke MySQL
database tabellen.
Source:
https://www.digitalocean.com/community/tutorials/how-to-create-django-models