Webapplicaties maken met Django - Introductie

Webapplicaties maken met Django - Introductie

8 augustus 2024
Erwin Matijsen
Geplaatst in Tutorial
Onderdeel van Werken met Django


Je komt Python op allerlei plekken tegen. Het is bijvoorbeeld groot in de data-analyse en machine learning / AI. Maar ook voor het maken van webapplicaties wordt Python veel gebruikt. Dit is mede te danken aan een aantal frameworks, die het ontwikkelen van een webapplicatie (of API) enorm vereenvoudigen. Een aantal veelgebruikte frameworks zijn Flask, FastAPI en Django.

Framework

Een framework is een set van tools, bibliotheken en best practices die helpen bij het opzetten van de projectstructuur, het afhandelen van veel voorkomende taken zoals interactie met de database, en het implementeren van beveiligingsmaatregelen.

Webapplicaties

Webapplicaties zijn overal. En dat is niet vreemd, want een webapplicatie komt met een aantal belangrijke voordelen. Allereerst ben je van het probleem af hoe je jouw applicatie bij de gebruiker krijgt. Ze hoeven niets te installeren, en je hebt nooit het probleem dat er verschillende versies in omloop zijn. Ten tweede is je applicatie direct beschikbaar op een groot aantal apparaten, of het nou een Windows-laptop, een iPad of een Linux-desktop is: allemaal hebben ze een browser die toegang biedt tot jouw applicatie. Dit laatste heeft ook als voordeel dat je ontwikkelkosten lager zijn, je hoeft immers maar één versie te maken.

Er zijn ook nadelen. Vanuit de browser heb je minder functionaliteit dan native op een smartphone of een laptop (alhoewel het verschil steeds kleiner wordt). Zo is het veel lastiger om push berichten te versturen, heb je geen integratie met een adresboek en geen toegang tot bijvoorbeeld NFC-chips. Een ander mogelijk nadeel is dat een webapplicatie een goede internetverbinding nodig heeft. Offline toegang bouwen kan wel, maar is veel beperkter dan bij een native applicatie.

Kortom: een webapplicatie is vaak een goede keuze, maar het hangt helemaal af van de functionaliteit die je jouw gebruikers wilt bieden.

Django

Heb je besloten een webapplicatie te maken, dan is Django een goede keuze. Het is een framework met, zoals ze zelf stellen, batteries included. Ofwel: het biedt heel veel hulpmiddelen zodat je dat allemaal zelf niet meer hoeft uit te werken. Een paar voorbeelden:

  • Routing (wat moet er gebeuren als er een bepaalde URL wordt ingetypt / op een knop wordt geklikt)
  • Formulieren, om gegevens te valideren
  • Werken met een database
  • Authorisatie en authenticatie van gebruikers
  • Caching
  • Templates om pagina's dynamisch op te bouwen
  • Allerlei beveiligingsmaatregelen
  • Een uitgebreide beheeromgeving

Met een framework is veel code al voor je geschreven. Stel je wilt een heel eenvoudige webapplicatie maken. Het enige dat het doet is als de gebruiker op je domein komt, er staat: "Hallo!". Toch moet je hier al veel voor programmeren. De browser stuurt een verzoek, en jouw code moet dit verzoek afhandelen en een resultaat teruggeven. Hier zijn veel stappen voor nodig, zoals het bepalen van de URL, het type verzoek (GET), welk resultaat erbij hoort ("Hallo!"), het terugsturen van de informatie...

Deze stappen zijn niet uniek voor jouw webapplicatie. Elke webapplicatie doorloopt voor een deel dezelfde stappen. Het voordeel van Django - en andere frameworks - is dat al deze basiscode al voor jou gemaakt is en beschikbaar is. Waarom zou je immers het wiel opnieuw uitvinden? Op deze manier kun jij je focussen op de toegevoegde waarde van jouw applicatie, iets dat het uniek maakt. Bijkomend voordeel is dat er al vele manuren in een framework zitten, en hierdoor de (meeste) fouten er uit zijn en alles volgens de best practices gaat. Dit maakt het vaak veiliger en betrouwbaarder dan je eigen oplossing.

Django verschilt van sommige andere frameworks door zijn uitgebreidheid. Er is echt al heel veel voor je gedaan. Hier kleeft een mogelijk nadeel aan: als jij bijvoorbeeld liever op een andere manier dan die van Django met de database communiceert, is dat lastiger. Django heeft veel ingebouwd, maar alles hangt ook erg samen. Passen sommige onderdelen niet goed bij wat je wil, dan kun je misschien beter een framework gebruiken dat echt alleen de basis afhandelt. De componenten die het framework niet biedt, kun je zelf implementeren of ergens anders vandaan halen.

Project

In dit project ga je een webapplicatie maken waarin je gegevens over je auto('s) kunt bijhouden, zoals hoeveel geld je kwijt bent aan aanschaf, onderhoud, brandstof, et cetera. Het project zal ook in latere tutorials gebruikt worden. In deze tutorial begin je bij het begin: kennismaken met Django. Je leert twee belangrijke dingen over Django. Ten eerste leer je hoe je een nieuwe Django project start en wat de algemene structuur van een Django-project is. Ten tweede leer je wat de request / response cyclus is. Begrijp je dit, dan zullen je verdere Django-avonturen een stuk eenvoudiger zijn.

Maak eerst een nieuwe map aan en installeer Django hierin.

shell
cd ~/projects
mkdir autotracker && cd autotracker
python -m venv .venv
source .venv/bin/activate  # .venv\Scripts\activate.bat voor Windows
python -m pip install django
python -m pip freeze > requirements.txt

Je hebt Django geïnstalleerd, maar het is nog geen Django project. Om van de map een Django-project te maken, gebruik je het hulpmiddel django-admin, onderdeel van de django-package die je net hebt geïnstalleerd.

shell
django-admin startproject conf .

Met django-admin startproject begin je een nieuw project. Het argument dat erna volgt (conf) is de naam die je de map wilt geven waar de basis van het project zich bevindt. Je zult heel vaak zien dat mensen dit hetzelfde noemen als de bovenliggende naam (dus autotracker in dit geval). Persoonlijk kies ik altijd voor conf, omdat het de plaats is waar je veel dingen instelt.

Het laatste argument - . - is de locatie waar je het project wilt installeren. In dit geval wil je het in de map autotracker plaatsen en bevind je je daar ook. Met de punt geef je aan: maak het project aan in de huidige map.

De structuur ziet er nu zo uit:

autotracker/
├── conf/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── requirements.txt

In je terminal kun je nu python manage.py runserver uitvoeren.

Let op: zorg ervoor dat je in de map autotracker bent en dat je de venv geactiveerd hebt.

Met dit commando start je een ontwikkelserver. Na een paar waarschuwingen over migraties (die je voor nu nog kunt negeren), zie je iets als:

Starting development server at http://127.0.0.1:8000/
Localhost

Het adres 127.0.0.1 wordt ook wel localhost genoemd. Je kunt dan vaak ook http://localhost:8000 gebruiken. Wil je meer weten over wat localhost precies is, lees dan het Wikipedia-artikel.

Gebruik de ontwikkelserver nooit in een productieomgeving. Het is handig voor de ontwikkeling, maar niet veilig of efficiënt voor productie. In een latere tutorial leer je hoe je een Django-project in productie kunt nemen.

Ga je in je browser nu naar dit adres, dan zie je een pagina waaruit blijkt dat je Django-project goed is aangemaakt.

Django-project is succesvol aangemaakt

Gefeliciteerd! Je eerste Django-project! Goed, het doet nog niets, maar het begin is er.

Apps

Omdat Django een framework is, is er een bepaalde indeling nodig om de dingen te laten werken. Een voorbeeld hiervan zag je al: er is een aparte map - die je conf hebt genoemd - met onder andere de instellingen.

Een ander voorbeeld is dat Django functionaliteit in apps ingedeeld wil hebben. In een app komen belangrijke zaken terug, zoals de interactie met je database. Het staat je echter vrij om je apps te noemen zoals je wilt, en ook hoeveel je er aan maakt. In een kleiner project zal één app volstaan. In een groter project kan het voor je eigen overzichtelijkheid handig worden om je apps te gaan splitsen. Hoé je dat doet, is aan jou. Vaak zal er vanzelf een logische indeling ontstaan op basis van de functionaliteit die je wilt bieden.

In een overzicht zit het er zo uit:

autotracker/
├── conf/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── app_1/
├── app_2/
├── manage.py
└── requirements.txt

Maak nu een app aan met het volgende commando:

shell
python manage.py startapp tracker 

Hierbij is tracker de naam van de app. Je project structuur ziet er nu als volgt uit:

autotracker/
├── conf/
├── tracker/
│   ├── migrations/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   └── tests.py
│   └── views.py
├── manage.py
└── requirements.txt

Request/Response cyclus

Eén van de belangrijkste dingen om te begrijpen is de request/response cyclus van Django. Om het te begrijpen, ga je zelf een (eenvoudige) cyclus implementeren.

URL

Elke cyclus begint bij de URL. Een gebruiker typt bijvoorbeeld een URL in, of klikt op een knop die naar een URL verwijst. In de map conf is al een bestand urls.py aangemaakt. In dit bestand vind je de lijst urlpatterns, met nu één element: path('admin/', admin.site.urls). Dit element kun je voor nu negeren.

Voeg onder de regel met 'admin/' de volgende regel toe:

conf/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home, name='home'),  # Voeg deze regel toe
]

Wat je hiermee doet is een nieuw path toevoegen. Een path is de koppeling tussen een URL en een view. De URL is in dit geval '', ofwel een lege string. In urlpatterns plaats je de paden die je wilt gebruiken, en dit zijn de delen ná domeinnaam (dus na http://127.0.0.1:8000/ in dit geval. Als je het live zou zijn, zou het bijvoorbeeld https://python-cursus.nl zijn). Omdat je een lege string hebt toegevoegd, verwijst dit pad dus naar de root, dus naar http://127.0.0.1:8000/.

Het tweede argument is home. Dit is de view, de functie die bepaalt welke informatie er wordt teruggegeven. Op dit moment bestaat de functie home nog niet en zal het dus nog niet werken.

Het laatste argument is de naam die je geeft aan dit pad, in dit geval home. Later kun je dit op andere plekken in je code gebruiken om dit pad aan te roepen.

View

Om het werkend te maken heb je nu een view genaamd home nodig. Een view is een functie (of een klasse) die een HTTP-verzoek verwerkt en een HTTP-antwoord teruggeeft. Een view bevat de logica van je applicatie. Het voert bijvoorbeeld berekeningen uit, haalt gegevens uit de database en bepaalt welke gegevens aan de gebruiker moeten worden getoond. Zoals je hierboven zag is elke URL (pad) gekoppeld aan een view.

Open tracker/views.py, verwijder alles wat je ziet en plaats vervolgens de volgende code:

tracker/views.py
from django.http import HttpResponse

def home(request):
    return HttpResponse("Welkom bij AutoTracker!")

In conf/urls.py kun je nu bovenin het bestand from tracker.views import home toevoegen. Als je de ontwikkelserver nog had draaien, kun je nu de pagina op http://127.0.0.1:8000/ verversen. Start anders de server weer met python manage.py runserver.

Als het goed is zie je nu een witte pagina met de tekst "Welkom bij AutoTracker!".

Je nieuwe homepage

Request / response

In de functie home, wat dus een view is, zie je dat de parameter request nodig is. Hier wordt in dit geval niets mee gedaan, maar elke view moét deze parameter hebben. Wat is request? Het is een HttpRequest-object, Django's manier om een HTTP-verzoek dat binnenkomt te verwerken. In conf/urls.py heb je een pad gekoppeld aan een view. Zodra een HTTP-verzoek voor het betreffende pad binnenkomt, maakt Django een HttpRequest-object aan met alle gegevens, en roept vervolgens de bijbehorende view aan met het HttpRequest-object als eerste argument.

Voorbeelden van gegevens die aan een HttpRequest zijn gekoppeld zijn:

  • Wat voor verzoek betreft het (GET, POST, PUT, DELETE)
  • Welke cookies zijn meegestuurd
  • Wat zijn de headers, met onder ander de user agent
  • Wat is de body (in geval van een POST of PUT)
  • Wat is het schema (http of https)
  • Wat is het content type, bijvoorbeeld text/html of multipart/form-data

Op basis van deze informatie kun je besluiten wat je wilt doen. Een veelgebruikte aanpak is bijvoorbeeld om in één view zowel de GET- als de POST-verzoeken af te handelen.

python
from django.http import HttpResponse

def home(request):
    if request.method == "POST":
        # Verwerk bijvoorbeeld een formulier
        return HttpResponse("Gegevens opgeslagen!")
    else:
        return HttpResponse("Vul je gegevens in")

De meeste communicatie over het internet verloopt via het HTTP-protocol. Een HTTP-verzoek is een verzoek van bijvoorbeeld een browser aan een server om een bepaalde resource terug te sturen, vaak een HTML-pagina. Er zijn verschillende HTTP-verzoek methodes, waaronder GET en POST. Met GET verzoek je om een bepaalde pagina op te halen. Met POST verzoek je om de meegestuurde informatie te verwerken.

Je ziet dat de view ook een HttpResponse terugstuurt. Net als een HttpRequest-object is het een object met allerlei informatie. Voorbeelden zijn:

  • De inhoud (in dit geval de tekst)
  • De statuscode: standaard 200 OK
  • Headers
  • Content-Type: standaard text/html
  • Cookies

Niet alle informatie is verplicht, zoals je in bovenstaande voorbeeld ziet.

Conclusie

In deze tutorial heb je kennis gemaakt met Django. Je weet nu hoe een Django-project opgebouwd is, en nog belangrijk: je hebt de basis geleerd van de request/response-cyclus. Voor nu is het echt nog de basis, maar het is een belangrijk fundament van Django.

Als je begrijpt dat alles begint bij een verzoek dat een HttpRequest-object oplevert en dat je uiteindelijk iets wilt terugsturen met een HttpResponse-object (of variant), dan ben je al een heel eind.

Werken met formulieren, met middleware, authenticatie, API's maken, werken met templates... alles kun je plaatsen in deze fundamentele cyclus.

Over de auteur


Erwin Matijsen

Erwin Matijsen

Erwin is de oprichter van python-cursus.nl. In allerlei rollen heeft hij Python ingezet, van het eenvoudiger maken van zijn werk tot het opleveren van complete (web)applicaties. Met vrouw en kinderen woont hij in Havelte (Drenthe), midden in de prachtige natuur. Daar wandelt hij graag, zeker ook omdat de beste ingevingen tijdens een wandeling - weg van de computer - lijken te komen.


Contact

Training volgen?

Heb je behoefte aan een in-person training voor jezelf of je team? Dat kan! Laat je gegevens achter en dan nemen we zo snel mogelijk contact met je op de mogelijkheden te bespreken.


Contact

Vragen, opmerkingen?

Heb je vragen, opmerkingen, suggesties of tips naar aanleiding van deze blog? Neem dan contact met ons op, of laat het weten via Mastodon of LinkedIN.