Hoe maak je Django-modellen

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:

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.

  1. cd ~/my_blog_app
  2. . env/bin/activate
  3. cd blog

Vanaf daar laten we deze opdracht uitvoeren:

  1. 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.

  1. cd ~/my_blog_app/blog/blogsite

Gebruik het cat-commando om de inhoud van het bestand in je terminal te tonen.

  1. 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.

models.py
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.

  1. 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.

models.py
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.

models.py
...
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.

models.py
...
    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.

models.py
...
    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.
models.py
...
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:

models.py
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.

  1. cd ~/my_blog_app/blog/blog

Vanaf hier, open je settings.py bestand, bijvoorbeeld met nano.

  1. nano settings.py

Met het bestand geopend, voeg je jouw blogsite app toe aan de INSTALLED_APPS sectie van het bestand, zoals hieronder aangegeven.

settings.py
# 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:

  1. cd ~/my_blog_app/blog

Voer vervolgens het makemigrations-commando uit op manage.py.

  1. python manage.py makemigrations

Je zou dan de volgende uitvoer in je terminalvenster moeten ontvangen:

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

  1. 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.

  1. python manage.py showmigrations
Output
admin [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:

  1. 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.

  1. python manage.py migrate

We zullen de volgende uitvoer ontvangen:

Output
Operations 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.

  1. 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.

  1. USE blog_data;

Typ vervolgens de volgende opdracht om de tabellen te bekijken.

  1. 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.

  1. 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)
  1. 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:

  1. 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