Django is een Python-framework op hoog niveau. Het is populair vanwege zijn eenvoud en efficiëntie bij het bouwen van robuuste webapplicaties.

De kern van de architectuur van Django is het Model-View-Template (MVT) patroon. Een goed begrip van hoe Modellen, Weergaven en Templates met elkaar interageren is cruciaal als je de volledige kracht van Django wilt benutten.

Of je nu helemaal nieuw bent met Django of een beginner, dit artikel zal dienen als een uitgebreide gids die je laat zien hoe deze componenten werken en met elkaar interageren om dynamische webapplicaties te creëren.

Om het nog begrijpelijker te maken, zullen we een eenvoudige applicatie bouwen om je een beter inzicht te geven in de onderlinge verbondenheid van deze componenten.

Als je al enthousiast bent, laten we er meteen induiken!

Dit is wat we zullen behandelen:

Vereisten

Om mee te doen, heb je nodig:

  • Basisbegrip van hoe webapplicaties werken, inclusief client-serverarchitectuur.

  • Basis kennis van Python.

Wat is de MVT-architectuur?

Het MVT-patroon is de benadering van Django voor het organiseren van de codebase en workflow van een webapplicatie. De componenten die deze architectuur vormen, zijn het Model, de View en de Template. Elke component voert specifieke functies uit en geeft vervolgens het proces door aan de andere componenten om hun taken uit te voeren.

Laten we snel kijken naar de componenten met de specifieke functies die ze uitvoeren:

  • Model: Ook bekend als de datalaag, beheert het gegevens en communiceert met de database.

  • View: Ook bekend als de logische laag, fungeert als tussenpersoon, behandelt logica en beheert de gegevensstroom.

  • Template: Ook bekend als de presentatielaag, rendert het HTML-inhoud op de gebruikersinterface.

Nu je een idee hebt over de componenten en hun rollen in een Django-applicatie, zullen we uitgebreid ingaan op elke component en hoe ze interactie hebben in de architectuur.

De Model Component

Modellen beheren de structuur en interactie van gegevens binnen een Django-applicatie, waardoor ze de basis van Django-apps vormen vanwege de cruciale rol die gegevens spelen.

Django-modellen maken gebruik van een krachtige functie genaamd Object-Relationele Mapping (ORM), die de kloof tussen een relationele database en Python-code overbrugt. Het zet de Python-objecten (klassen) om in databasetabellen, hun attributen in kolommen en instanties in rijen binnen die tabellen.

Één groot voordeel van de ORM is dat het je in staat stelt om te communiceren met de database met behulp van Python-objecten in plaats van SQL-query’s te schrijven. Zie het als een vertaler die de ene taal in de andere omzet zodat een publiek het kan begrijpen. In dit geval vertaalt de ORM Python-code naar SQL-commando’s die de database kan uitvoeren, en vice versa.

Django-modellen omvatten alle op de database gerelateerde logica en definiëren de structuur van je database, als een blauwdruk voor de gegevens die je wilt opslaan.

Algemene opmaak van een Django-model

In Django volgt elk model een bepaalde manier van declaratie. Hier is de basisstructuur van een modeldeclaratie:

class <model_name>(models.Model):
    <field_name> = models.<field_type>(<optional_field_characteristics>)

Laten we het uitsplitsen:

  • class: het trefwoord dat wordt gebruikt om een model in Django te definiëren.

  • model_naam: de naam van het model.

  • models.Model: de basisklasse waarvan de modelklasse erft.

  • field_name: de naam van de databasekolom.

  • field_type: verwijst naar het type gegevens dat het veld bevat, zoals CharField, BooleanField enzovoort.

  • optional_field_characteristics: wordt gebruikt om verder te definiëren hoe het veld zich gedraagt, zoals max_length, default, enzovoort.

Modelvoorbeeld

Met alles wat we tot nu toe weten over modellen, zullen we er een construeren voor een takenlijst. Het bevat doorgaans de taken titel, beschrijving en een indicatie of de taken voltooid zijn of niet.

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

In dit model:

  • Task is de naam van het model.

  • Het Taakmodel heeft drie velden:

    • titel: Een CharField dat tekst bevat, met een maximale lengte van 100 tekens.

    • omschrijving: Een TextField voor langere tekst.

    • voltooid: Een BooleanField die een waarde van True of False opslaat, met een standaardwaarde van False.

De Weergavecomponent

Django-weergaven zijn verantwoordelijk voor het verwerken van gebruikersverzoeken en het retourneren van antwoorden. Ze fungeren als de brug tussen het Model en de Template door gegevens te verzamelen uit Modelobjecten, logische bewerkingen uit te voeren op deze gegevens (zoals query’s op basis van bepaalde criteria), en vervolgens de gegevens door te geven aan de template voor weergave.

Views kunnen worden geschreven als functies of op basis van klassen, afhankelijk van de complexiteit en vereisten van je applicatie.

Algemeen Formaat van een Django View

Hier is de basisstructuur van een View:

def <view_name>(request):
    # View Logica gaat hier....
    return render(request, <template>, <context>)

Laten we het opsplitsen:

  • view_name: de naam van de viewfunctie.

  • request: de HTTP-aanroep die door de client naar de Django-server is verzonden, kan worden geactiveerd door formulierindieningen of door op een knop te klikken.

  • return render: gebruikt om de HTML-respons te genereren. Het neemt:

    • request: het aanvraagobject, dat informatie bevat over de binnenkomende aanvraag.

    • template: het sjabloonbestand dat moet worden weergegeven.

    • context: bevat variabelen die beschikbaar moeten worden gesteld in het sjabloon, meestal in de vorm van een woordenboek.

Voorbeeld bekijken

Als we doorgaan met onze Takenlijst, zou ons weergave er als volgt uitzien:

def task_list(request):
    # Logica komt hier...
    return render(request, <template>, {'tasks': tasks})

De Sjablooncomponent

Django-sjablonen zijn verantwoordelijk voor het renderen van de uiteindelijke HTML-uitvoer in de browser. Ze definiëren hoe gegevens moeten worden gepresenteerd door een combinatie van HTML en Django’s sjabloontaal te gebruiken.

De Django-sjabloontaal omvat het gebruik van sjabloon-tags {% %} en sjabloonvariabelen {{ }} waarmee je Django-modus kunt invoeren in je HTML-sjabloon. In deze modus kun je variabelen die in je weergaven zijn gedefinieerd benaderen en besturingsstructuren gebruiken binnen je sjabloon.

Sjablonen kunnen ook worden gestileerd met behulp van CSS of een van je favoriete CSS-frameworks om je gebruikersinterface aantrekkelijker te maken.

Sjabloonnvoorbeeld

Ons sjabloon is een normaal HTML-bestand met de sjabloontaal van Django. Zo zou onze Takenlijstsjabloon eruitzien:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>
</body>
</html>

In dit sjabloon:

  • De for-lus doorloopt elke taak in de lijst taken (herinner je je dat het als context is doorgegeven in onze weergaven).

  • Voor elke taak geeft het de titel van de taak en de voltooid-status weer (als “Klaar” of “Niet Klaar”).

  • Als de lijst taken leeg is, toont het {% leeg %}-blok een fallback-bericht met de tekst “Geen taken beschikbaar”.

Diagram dat de MVT-werkstroom toont

Deze diagram geeft weer hoe gegevens stromen binnen de MVT-architectuur van Django:

Realistische analogie van MVT

Stel je voor dat je naar een restaurant gaat en een bestelling plaatst voor je favoriete maaltijd. Achter de schermen heeft het restaurant een receptenboek dat beschrijft hoe elk gerecht moet worden bereid. De chef gebruikt de recepten om jouw maaltijd precies te bereiden zoals je het hebt besteld. Zodra het klaar is, brengt de ober je de maaltijd op een presentabele manier.

Net zoals een chef het recept volgt om het gerecht te bereiden, gebruikt de View het Model om gegevens te verzamelen en te verwerken. Tenslotte, net zoals de ober het gerecht serveert, zorgt de Template ervoor dat de eindoutput op een duidelijke en boeiende manier aan de gebruiker wordt gepresenteerd.

Het samenvoegen tot een project

Deze sectie leidt je stap voor stap door het opzetten van de Taaklijst die we als voorbeeld in het artikel hebben gebruikt. Aan het einde zou je een functionele applicatie moeten hebben met de MVT-architectuur in volle gang.

Installeer Python

Zorg er eerst voor dat je Python hebt geïnstalleerd. Je kunt de Officiële Website van Python bezoeken om de nieuwste versie van Python te downloaden.

Stel het Django-project en de app in

Installeer vervolgens Django. Je kunt het installeren met pip:

pip install django

Maak een map aan en open deze in je favoriete code-editor.

Maak een nieuw Django-project en een app door de volgende opdrachten in je terminal uit te voeren, één voor één:

django-admin startproject myproject 
cd myproject
django-admin startapp myapp

Definieer het Model

In je myapp/models.py:

from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

Maak een Formulier

We hebben een Django-formulier nodig op basis van het Taakmodel, dus we zullen er een maken met behulp van de Django ModelForm.

In je myapp, maak een bestand aan, noem het forms.py, en voeg deze code in:

from django import forms
from .models import Task

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['title', 'description', 'completed']

In deze code:

  • Task is geïmporteerd vanuit .models.

  • class TaskForm(forms.ModelForm): Dit maakt een nieuwe klasse genaamd TaskForm, die een subklasse is van forms.ModelForm.

  • class Meta:: is een speciale klasse die wordt gebruikt door de ModelForm van Django om configuratie voor het formulier te bieden. De Meta klasse vertelt Django hoe het formulier moet worden gemaakt door het bijbehorende model en de velden die in het formulier moeten worden opgenomen, te specificeren.

  • model = Taak: specificeert het model waarop het formulier is gebaseerd. In dit geval is het formulier gebaseerd op het model Taak.

  • velden = ['titel', 'omschrijving', 'voltooid']: specificeert welke velden uit het model Taak moeten worden opgenomen in het formulier. Hiermee kunt u bepalen welke modelvelden in het formulier verschijnen, en het kan worden aangepast om alleen bepaalde velden op te nemen, in plaats van alle velden in het model.

Maak de Weergave

In uw myapp/views.py, voeg deze code toe:

from django.shortcuts import render,redirect
from .models import Task
from .forms import TaskForm

def task_list(request):
    tasks = Task.objects.all()    # Haal alle taken op

    if request.method == 'POST':    # Verwerk formulierindieningen
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('task_list')  # Redirect om dubbele indieningen te voorkomen
    else:
        form = TaskForm()

    # Geef taken en het formulier door aan de sjabloon
    return render(request, 'task_list.html', {'tasks': tasks, 'form': form})

In deze weergave,

  • TaskForm wordt geïmporteerd uit forms.

  • De code controleert of de aanvraagmethode POST is, wat aangeeft dat de gebruiker een formulier heeft ingediend.

  • Als de methode POST is, wordt er een instantie van TaskForm aangemaakt met de ingediende gegevens (request.POST).

  • Het formulier wordt vervolgens gevalideerd met form.is_valid(), en als het geldig is, wordt het formulier opgeslagen in de database.

  • Na het opslaan wordt de gebruiker doorgestuurd naar de taaklijstpagina om dubbele inzendingen te voorkomen.

Definieer de sjabloon

In uw myapp-map maakt u een map templates aan. Maak binnen de map templates een bestand aan met de naam task_list.html. We moeten een formulierelement toevoegen dat de gebruikersinvoer verzamelt en deze op de UI in een lijst weergeeft.

In het HTML-bestand task_list hebben we:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>

    <h2>Add a New Task</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Add Task</button>
    </form>
</body>
</html>

In de toegevoegde formuliercode:

  • We hebben een HTML-formulier gemaakt met de POST-methode voor het indienen van gegevens. Het bevat een {% csrf_token %} om te beschermen tegen CSRF-aanvallen.

  • De formulievelden worden weergegeven met {{ form.as_p }}, dat elk veld binnen een <p>-tag weergeeft.

  • Tenslotte is er een verzendknop met de naam “Taak toevoegen”, waarmee de gebruiker de formuliergegevens kan verzenden.

Mapstructuur

Eenmaal op dit punt aangekomen, is het belangrijk om te controleren of je je app op de juiste manier configureert. Zo zou je map-/bestandsstructuur eruit moeten zien:

└── 📁myproject
    └── 📁myapp
        └── 📁__pycache__
        └── 📁migrations
        └── 📁templates
            └── task_list.html
        └── __init__.py
        └── admin.py
        └── apps.py
        └── forms.py
        └── models.py
        └── tests.py
        └── urls.py
        └── views.py
    └── 📁myproject
        └── 📁__pycache__
        └── __init__.py
        └── asgi.py
        └── settings.py
        └── urls.py
        └── wsgi.py
    └── db.sqlite3
    └── manage.py

Configureer de URL van het project

In je myproject/urls.py, voeg de URL toe aan je myapp:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),
]

Voeg de app toe aan de projectinstellingen

Voeg je myapp toe aan de lijst van Geïnstalleerde apps in je myproject/settings.py:

INSTALLED_APPS = [
    'myapp',      # onze myapp-app toegevoegd
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Start de server

Voer migratie uit en start de server door deze opdrachten in te voeren:

python manage.py migrate

python manage.py runserver

Bezoek http://127.0.0.1:8000/ in je browser om je app te testen.

Laatste look

Zo ziet onze takenlijst-app eruit in de browser nadat we wat taken hebben toegevoegd met behulp van het formulier. Je kunt verdere verbeteringen aanbrengen in de vormgeving van de template zoals je wilt.

Conclusie

In dit artikel heb je geleerd over de componenten in de MVT-architectuur van Django, hoe ze met elkaar interageren en hoe ze webervaringen naadloos maken. We hebben ook een eenvoudig project gebouwd om te zien hoe het in de praktijk werkt, en ik hoop dat je het nu beter begrijpt.

Als je genoten hebt van het lezen van dit artikel, kun je me volgen op X of met me verbinden op LinkedIn voor meer programmeerartikelen en berichten.

Tot de volgende keer!