1 2021-10-01

1.1 Django installeren

Maak een nieuwe virtual environment en installeer hierin Django met behulp van pip.

Maak een Django project aan met:

django-admin startproject twitter

Voer het volgende commando uit om de datebase aan te maken:

python manage.py migrate

Maak een admin gebruiker aan:

python manage.py createsuperuser

1.2 Django app

Maak een Django app aan met:

python manage.py startapp tweet

Voeg de app aan je project toe (twitter/settings.py) en zoek naar een lijst met naam INSTALLED_APPS. Voeg ‘tweet’ aan de lijst toe.

1.3 Data model toevoegen

Open tweet/models.py en voeg onderstaande code toe:

class Tweet(models.Model):
    msg = models.CharField(max_length=128)
    timestamp = models.DateTimeField(auto_now_add=True)

Maak migratiescripts en voer deze uit om de database aan te passen.

Het DateTimeField laat toe om een tijdstip in je tabel op te slaan. De auto_now_add parameter zorgt ervoor dat het veldje automatisch ingevuld wordt.

1.4 App aan admin toevoegen

Breid de admin uit zodat je tweets kan aanmaken vanuit de admin.

1.5 String conversie toevoegen

Als je de tweets in de admin bekijkt, zie je nu de omschrijving ‘Tweet object’. De reden hiervoor is dat Python de object naar een string probeert om te zetten, en dit is de standaard manier om dit te doen. Om een handigere voorstelling te krijgen, kan je een __str__ method toevoegen, zoals in onderstaande code.

Open tweet/models.py en pas de code aan:

class Tweet(models.Model):
    msg = models.CharField(max_length=128)
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.msg

1.6 Database model uitbreiden

We voegen nu een veld ‘likes’ toe.

Open tweet/models.py en pas je code aan:

class Tweet(models.Model):
    msg = models.CharField(max_length=128)
    timestamp = models.DateTimeField(auto_now_add=True)
    likes = models.PositiveIntegerField(default=0) # aangepast

    def __str__(self):
        return self.msg

Maak migratiescripts en voer deze uit om de database aan te passen.

1.7 Django generic views

Tot nu toe kunnen we de database gegevens enkel via de admin benaderen.

We breiden onze code nu uit, zodat we ook via een eigen webpagina’s aan de data kunnen.

Open tweet/views.py en voeg onderstaande code toe:

from django.views.generic import ListView
from .models import Tweet

class TweetListView(ListView):
        model = Tweet

Open twitter/urls.py en voeg onderstaande code toe:

from tweet.views import TweetListView
urlpatterns += [
        path('tweet/', TweetListView.as_view()),
]

Bekijk de website op http://localhost:8000/tweet/

Je krijgt een foutmelding over een ontbrekend ‘template’ bestand ‘tweet_list.html’.

We dienen dit bestand nu op de juiste locatie aan te maken: - Maak een map aan in de ‘tweet’ map met naam ‘templates’. - Maak hierin een map met naam ‘tweet’. - Maak in deze map een bestand aan met naam ‘tweet_list.html’. - Schrijf volgende code in dit bestand:

{% for tweet in object_list %}
  {{ tweet }}
{% endfor %}

Voeg via de admin een aantal twitter-tweets toe, en surf vervolgens opnieuw naar http://localhost:8000/tweet

1.8 Django templates

Tot nu toe was de output op de tweet list pagina te eenvoudig.

Pas de code als volgt aan:

{% for tweet in object_list %}
   {{ tweet.msg }}
{% endfor %}

Herlaad de webpagina, en merk op dat alles op 1 regel verschijnt.

Pas de code aan zodat de tweets op verschillende regels verschijnen. De code in het ‘tweet_list.html’ bestand is HTML, dus je kan b.v. ‘<br>’ gebruiken.

1.9 Detail pagina

We breiden onze code nu uit, zodat we ook via een eigen webpagina’s aan de data kunnen.

Open tweet/views.py en pas onderstaande code aan:

from django.views.generic import ListView, DetailView
from .models import Tweet

class TweetListView(ListView):
        model = Tweet

class TweetDetailView(DetailView):   # nieuw
        model = Tweet                # nieuw

Open twitter/urls.py en pas onderstaande code aan:

from tweet.views import TweetListView, TweetDetailView
urlpatterns += [
        path('tweet/', TweetListView.as_view()),
        path('tweet/<int:pk>', TweetDetailView.as_view()), # nieuw
]

Voeg een bestand ‘tweet_detail.html’ toe in dezelfde map als ‘tweet_list.html’:

Message: {{ object.msg }}
Likes: {{ object.likes }}
Timestamp: {{ object.timestamp }}

1.10 Verwijzen naar de detailpagina

We willen vanuit de lijstpagina kunnen doorlinken naar de overeenkomstige detailpagina’s.

Pas de code als volgt aan:

{% for tweet in object_list %}
   <a href="/tweet/{{ tweet.pk }}">
   {{ tweet.msg }}
   </a>
{% endfor %}

1.11 Uitbreiden admin

Pas de ‘admin.py’ file aan:

from django.contrib import admin

from .models import Tweet

class TweetAdmin(admin.ModelAdmin):
    search_fields = ['msg']


admin.site.register(Tweet, TweetAdmin)

Het ‘search_fields’ veld zorgt ervoor dat je kan zoeken in de opgegeven velden.

Het ‘list_display’ veld zorgt ervoor dat je kan bepalen welke kolommen in de lijstvoorstelling verschijnen.

Voeg een veldje ‘list_display’ toe met als waarde [‘timestamp’, ‘likes’, ‘msg’].

Het ‘date_hierarchy’ veld zorgt ervoor dat je door de jaren, maanden kunt browsen.

Voeg een veldje ‘date_hierarchy’ toe met als waarde ‘timestamp’.

1.12 Vermijden duplicatie template-code

Je hebt nu twee template bestanden gemaakt:

  • tweet_list.html

  • tweet_detail.html

Typisch heb je grote stukken HTML-code die gemeenschappelijk zijn voor iedere pagina van je website. Zo heb je bijvoorbeeld onderaan een ‘footer’ met copyright informatie, bovenaan een menu-balk, etc.

Django voorziet ‘base templates’ om code duplicatie te vermijden.

Voeg een HTML bestand ‘base.html’ toe in de map met templates met inhoud:

Dit is het begin.

{% block content %}
{% endblock %}

Dit is het einde.

Pas ‘tweet_detail.html’ als volgt aan:

{% extends 'tweet/base.html' %}

{% block content %}
Message: {{ object.msg }}
Likes: {{ object.likes }}
Timestamp: {{ object.timestamp }}
{% endblock %}

Bekijk de detail pagina opnieuw. Wat verschijnt er nu op deze pagina?

Pas nu ook ‘tweet_list.html’ op dezelfde manier aan.

Alle aanpassingen die je nu in ‘base.html’ doet, verschijnen nu op alle pagina’s