Dans ce tutoriel, nous allons créer une application de blog avec Django, l'application permet aux utilisateurs de créer, modifier et supprimer des articles. La page d'accueil affichera tous les articles du blog, et il y aura une page détaillée dédiée pour chaque article individuel. Django est capable de réaliser des choses plus avancées, mais la création d'un blog est une excellente première étape pour se familiariser avec le framework. L'objectif de cet article est d'avoir une idée générale du fonctionnement de Django.

Voici le rendu final de notre blog.

Qu'est-ce que Python Django?

Django est un incroyable framework de développement Web gratuit et open source qui permet aux développeurs de créer facilement des applications et sites Web. C'est le framework idéal pour apprendre la programmation web.

Pré-requis

Étant donné que Python 3 est la version en cours de développement et qu'elle est considérée comme l'avenir de Python, Django a effectué une mise à jour importante, et maintenant toutes les versions postérieures à Django 2.0 ne sont compatibles qu'avec Python 3.x. Par conséquent, ce tutoriel est strictement destiné à Python 3.x. Assurez-vous que Python 3 est installé sur votre machine, sinon suivez les guides ci-dessous.

Création d'environnements virtuels

"Le module venv permet de créer des "environnements virtuels" légers avec leurs propres dossiers site, optionnellement isolés des dossiers site système. Chaque environnement virtuel a son propre binaire Python (qui correspond à la version du binaire qui a été utilisée pour créer cet environnement) et peut avoir sa propre liste de paquets Python installés dans ses propres dossiers site."

Créer un environnement virtuel

La création d'environnements virtuels est faite en exécutant la commande venv:

python3 -m venv /path/to/blogenv

Sur Windows, lancez la commande comme suit:

c:\>c:\Python35\python -m venv c:\path\to\blogeng

Activer l'environnement virtuel

Pour activer l'environnement, tapez cette commande:

source blogenv/bin/activate

et sur Windows:

. blogenv\scripts\activate

Installation de Django

Pour installer Django sur notre machine, l'option recommandée est d'utiliser un gestionnaire de package comme pipenv, venv, virtualenv etc.

Dans ce tutoriel, nous allons utiliser venv comme gestionnaire de package. Tapez cette commande, pour installer Django sur votre environnement virtuel.

❯ pip3 install django
Collecting django
  Downloading Django-4.1.1-py3-none-any.whl (8.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1/8.1 MB 8.1 MB/s eta 0:00:00
Collecting asgiref<4,>=3.5.2
  Downloading asgiref-3.5.2-py3-none-any.whl (22 kB)
Collecting sqlparse>=0.2.2
  Downloading sqlparse-0.4.2-py3-none-any.whl (42 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.3/42.3 kB 2.5 MB/s eta 0:00:00
Installing collected packages: sqlparse, asgiref, django
Successfully installed asgiref-3.5.2 django-4.1.1 sqlparse-0.4.2

Créer un nouveau projet Django

Dans  votre dossier du travail, créez un dossier appelé djangoblog.

mkdir djangoblog && cd djangoblog

Exécutez maintenant la commande suivante dans votre shell(terminnal / cmd) pour créer un projet Django.

django-admin startproject djangoblog .

Cette commande va générer le dossier et les fichiers suivants, ouvrez le projet avec votre éditeur de code.

Ces fichiers sont :

  • Le premier répertoire racine djangoblog/ est un contenant pour votre projet. Son nom n’a pas d’importance pour Django ; vous pouvez le renommer comme vous voulez.
  • manage.py : un utilitaire en ligne de commande qui vous permet d’interagir avec ce projet Django de différentes façons. Vous trouverez toutes les informations nécessaires sur manage.py dans django-admin et manage.py.
  • Le sous-répertoire djangoblog/ correspond au paquet Python effectif de votre projet. C’est le nom du paquet Python que vous devrez utiliser pour importer ce qu’il contient (par ex. djangoblog.urls).
  • djangoblog/__init__.py : un fichier vide qui indique à Python que ce répertoire doit être considéré comme un paquet. Si vous êtes débutant en Python, lisez les informations sur les paquets (en) dans la documentation officielle de Python.
  • djangoblog/settings.py : réglages et configuration de ce projet Django. Les réglages de Django vous apprendra tout sur le fonctionnement des réglages.
  • djangoblog/urls.py : les déclarations des URL de ce projet Django, une sorte de « table des matières » de votre site Django. Vous pouvez en lire plus sur les URL dans Distribution des URL.
  • djangoblog/asgi.py : un point d’entrée pour les serveurs Web compatibles aSGI pour déployer votre projet.
  • djangoblog/wsgi.py : un point d’entrée pour les serveurs Web compatibles WSGI pour déployer votre projet.

Ensuite, nous devons créer une application Django appelée blog. Une application Django existe pour effectuer une tâche particulière. Vous devez créer des applications spécifiques qui sont chargées de fournir à votre site les fonctionnalités souhaitées.

Au niveau de manage.py executez la commande suivante, elle va créer un dossier blog avec des fichiers dedans.

python3 manage.py startapp blog

Maintenant nous devons informer Django qu'une nouvelle application a été créée, ouvrez votre fichier settings.py et faites défiler jusqu'à la section des applications installées, qui devrait contenir quelques applications déjà installées. Ajoutez l'application blog en dessus.

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog', # nouveau
]

Ensuite, effectuez les migrations.

python3 manage.py migrate

Démarrer le serveur pour tester notre blog.

python3 manage.py runserver

L'application s'est bien démarré sans problème, visitez votre site via http://127.0.0.1:8000/ vous devez voir quelques choses comme ça.

Les modèles de base de données

Nous allons maintenant définir les modèles de données pour notre blog. Un modèle est une classe Python qui sous-classe django.db.models.Model, dans laquelle chaque attribut représente un champ de la base de données. En utilisant cette fonctionnalité de sous-classe, nous avons automatiquement accès à tout ce qui se trouve dans django.db.models.Models et nous pouvons ajouter des champs et des méthodes supplémentaires si nécessaire. Nous aurons un modèle Article dans notre base de données pour stocker les articles.

from django.db import models
from django.contrib.auth.models import User


STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Article(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='articles')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

En haut, nous importons la classe models et créons une sous-classe de models.Model Comme tout blog typique, chaque article de blog aura un titre, un slug, un nom d'auteur et le timestamp ou la date de publication ou de dernière mise à jour de l'article.

Remarquez que nous avons déclaré un tuple pour le STATUS d'un article afin de séparer les brouillons et les articles publiés lorsque nous les rendons à l'aide de modèles.

La classe Meta à l'intérieur du modèle contient des métadonnées. Nous indiquons à Django de trier les résultats du champ created_on dans l'ordre décroissant par défaut lorsque nous interrogeons la base de données. Nous spécifions l'ordre décroissant en utilisant le préfixe négatif. En procédant ainsi, les messages publiés récemment apparaîtront en premier.

La méthode __str__() est la représentation lisible par l'homme par défaut de l'objet. Django l'utilisera à de nombreux endroits, comme le site d'administration.

Maintenant que notre nouveau modèle de base de données est créé, nous devons créer un nouvel enregistrement de migration pour celui-ci et migrer le changement dans notre base de données.

$ python manage.py makemigrations
Migrations for 'blog':
  blog/migrations/0001_initial.py
    - Create model Article
$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
  Applying blog.0001_initial... OK

Nous avons tout ce qu'il faut pour notre base de données, passons à l'étape de l'administration du site.

Administration de Django

Nous allons créer un panneau d'administration pour créer et gérer les articles. Heureusement, Django dispose d'une interface d'administration intégrée pour de telles tâches.

Afin d'utiliser l'interface d'administration de Django, nous devons d'abord créer un superutilisateur en exécutant la commande suivante dans le terminal/cmd.

❯ python3 manage.py createsuperuser

Vous serez invité à saisir votre adresse électronique, votre mot de passe et votre nom d'utilisateur. Notez que pour des raisons de sécurité, le mot de passe ne sera pas visible.

Username (leave blank to use 'macbookpro'): admin
Email address: [email protected]
Password:
Password (again):
Superuser created successfully.

Entrez les détails que vous pouvez toujours changer plus tard. Après cela, relancez le serveur de développement et allez à l'adresse http://127.0.0.1:8000/admin/. Mettez vos détails et cliquez sur le button Log in.

Faites un tour et tester les applications existantes dans l'administration.

Cependant, nous ne pouvons pas créer d'article à partir du panneau, nous devons ajouter le modèle Blog à notre administration.

Ajout de modèles au site d'administration

Ouvrez le fichier blog/admin.py et enregistrez-y le modèle Article comme suit.

from django.contrib import admin
from .models import Article

admin.site.register(Article)

Sauvegardez le fichier et rafraîchissez la page. Vous devriez voir apparaître le modèle d'article.

Maintenant, créons notre premier article de blog en cliquant sur l'icône Ajouter à côté de Article, ce qui vous amènera à une autre page où vous pourrez créer un article. Remplissez les formulaires respectifs et créez votre tout premier article.

Cliquez sur "Save". vous venez de créer votre premier article.

Bien qu'il fasse le travail, nous pouvons personnaliser la façon dont les article sont affichées dans le panneau d'administration selon notre convenance. Ouvrez à nouveau le fichier blog/admin.py et remplacez-le par le code ci-dessous.

from django.contrib.admin.decorators import register
from django.contrib import admin

from .models import Article

@register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}

Sauvegardez le fichier et rafraîchissez la page. Vous devriez voir apparaître les articles comme suit.

Notez que j'ai ajouté quelques articles pour les tester.

L'attribut list_display fait ce que son nom suggère : afficher les propriétés mentionnées dans le tuple dans la liste des messages pour chaque message.

Si vous remarquez à droite, il y a un filtre qui filtre les messages en fonction de leur statut, ce qui est fait par la méthode list_filter.

Et maintenant nous avons une barre de recherche en haut de la liste, qui va chercher dans la base de données à partir des attributs search_fields. Le dernier attribut prepopulated_fields remplit le slug, maintenant si vous créez un article, le slug sera automatiquement rempli en fonction de votre titre.

Maintenant que notre modèle de base de données est complet, nous devons créer les vues, les URL et les modèles nécessaires pour pouvoir afficher les informations sur notre application Web.

Écriture de vues

Une vue est une fonction Python acceptant une requête web et renvoyant une réponse web. Cette réponse peut contenir le contenu HTML d’une page web, une redirection, une erreur 404, un document XML, une image… ou vraiment n’importe quoi d’autre. La vue elle-même contient la logique nécessaire pour renvoyer une réponse. Ce code peut se trouver à l’emplacement de votre choix, pour autant qu’il soit dans le chemin Python.

Nous allons utiliser des vues basées sur des classes, puis mapper des URL pour chaque vue et créer un template HTML pour les données renvoyées par les vues.

Ouvrez le fichier blog/views.py et ajoutez le code ci-dessus.

from django.views import generic
from .models import Article

class ArticleList(generic.ListView):
    queryset = Article.objects.filter(status=1)
    template_name = 'index.html'

class ArticleDetail(generic.DetailView):
    model = Article
    template_name = 'article_detail.html'

Les ListViews intégrées, qui sont une sous-classe des vues génériques basées sur des classes, rendent une liste avec les objets du modèle spécifié, il suffit de mentionner le modèle, de même que les DetailViews fournissent une vue détaillée pour un objet donné du modèle au template fourni.

Ajouter les urls

Nous devons mapper l'URL pour les vues que nous avons créées ci-dessus. Lorsqu'un utilisateur fait une requête pour une page de votre application web, le contrôleur Django prend le relais pour rechercher la vue correspondante via le fichier urls.py, puis renvoie la réponse HTML ou une erreur 404 not found, si elle n'est pas trouvée.

Créez un fichier urls.py dans le répertoire de votre application de blog et ajoutez le code suivant.

# blog/urls.py
from . import views
from django.urls import path

urlpatterns = [
    path('', views.ArticleList.as_view(), name='home'),
    path('<slug:slug>/', views.ArticleDetail.as_view(), name='article_detail'),
]

Nous avons mappé des modèles généraux d'URL pour nos vues en utilisant la fonction path. Le premier modèle prend une chaîne vide désignée par ' ' et renvoie le résultat généré par la vue ArticleList qui est essentiellement une liste d'articles pour notre page d'accueil et enfin nous avons un paramètre facultatif nom qui est essentiellement un nom pour la vue qui sera plus tard utilisé dans les modèles.

Les noms sont un paramètre facultatif, mais c'est une bonne pratique de donner des noms uniques et mémorisables aux vues, ce qui facilite notre travail lors de la conception des modèles et permet de garder les choses organisées lorsque le nombre d'URL augmente.

Ensuite, nous avons l'expression généralisée pour les vues ArticleDetail qui résout le slug (une chaîne de caractères composée de lettres ou de chiffres ASCII). Django utilise les crochets < > pour capturer les valeurs de l'URL et renvoyer la page de détails équivalente.

Maintenant, nous devons inclure ces URL de blog dans le projet actuel. Pour ce faire, ouvrez le fichier djangoblog/urls.py et modifiez le comme suit.

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

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

Création de templates pour les vues

Nous en avons terminé avec les modèles et les vues. Nous devons maintenant créer des modèles pour afficher le résultat à nos utilisateurs. Pour utiliser les templates Django, nous devons d'abord configurer les paramètres des templates.

Créez le répertoire templates dans le répertoire de base. Maintenant ouvrez le fichier settings.py du projet et juste en dessous de BASE_DIR ajoutez la route vers le répertoire template comme suit.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / "djangoblog" / "templates"], # nouveau
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Maintenant, enregistrez et fermez le fichier, nous en avons terminé avec les configurations.

Django permet de séparer python et HTML, le python va dans les vues et le HTML dans les modèles. Django possède un puissant langage de modèles qui vous permet de spécifier comment les données sont affichées. Il est basé sur des balises de template, des variables de template et des filtres de template.

Je vais commencer par un fichier base.html et un fichier index.html qui en hérite. Plus tard, lorsque nous ajouterons des templtes pour la page d'accueil et les pages détaillées des articles, ils pourront également hériter de base.html.

Commençons par le fichier base.html qui contiendra les éléments communs à toutes les pages du blog, comme la barre de navigation et le pied de page. Nous utilisons également Bootstrap pour l'interface utilisateur.

Intégration de Bootstrap sur le fichier base.html

<!DOCTYPE html>
<html>

<head>
  <title>Xarala - Django Blog</title>
  <meta name="google" content="notranslate" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
</head>

<body>
  <style>
    body {
      font-family: "Roboto", sans-serif;
      font-size: 17px;
      background-color: #fdfdfd;
    }

    .shadow {
      box-shadow: 0 4px 2px -2px rgba(0, 0, 0, 0.1);
    }

    .btn-danger {
      color: #fff;
      background-color: #f00000;
      border-color: #dc281e;
    }

    .masthead {
      background: #3398E1;
      height: auto;
      padding-bottom: 15px;
      box-shadow: 0 16px 48px #E3E7EB;
      padding-top: 10px;
    }
  </style>

  <!-- Navigation -->
  <nav class="navbar navbar-expand-lg navbar-light bg-light shadow" id="mainNav">
    <div class="container-fluid">
      <a class="navbar-brand" href="{% url 'home' %}">Blog avec Django</a>
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse"
        data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false"
        aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarResponsive">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item text-black">
            <a class="nav-link text-black font-weight-bold" href="#">A propos</a>
          </li>
          <li class="nav-item text-black">
            <a class="nav-link text-black font-weight-bold" href="#">Contact</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>
  {% block content %}
  <!-- Le contenu de notre application -->
  {% endblock content %}
  <!-- Footer -->
  <footer class="py-3 bg-grey">
    <p class="m-0 text-dark text-center ">Copyright &copy; Xarala</p>
  </footer>
</body>

</html>
djangoblog/templates/base.html

Il s'agit d'un fichier HTML normal, à l'exception des balises situées entre accolades { }, appelées balises de template/template tag.

La balise {% url 'home' %} Renvoie une référence de chemin absolu, ce qui génère un lien vers la vue d'accueil, qui est également la vue Liste des articles.

La balise {% block content %} Définit un bloc qui peut être remplacé par des templates enfants, c'est là que le contenu de l'autre fichier HTML sera injecté.

Ensuite, créez le fichier index.html de notre blog qui est la page d'accueil.

{% extends "base.html" %}
{% block content %}
<style>
  body {
    font-size: 18px;
    background-color: #fdfdfd;
  }

  .head_text {
    color: white;
  }

  .card {
    box-shadow: 0 16px 48px #E3E7EB;
  }
</style>

<header class="masthead">
  <div class="overlay"></div>
  <div class="container">
    <div class="row">
      <div class=" col-md-8 col-md-10 mx-auto">
        <div class="site-heading">
          <h3 class=" site-heading my-4 mt-3 text-white"> Bienvenue chez Xarala </h3>
          <p class="text-light">Nous reinventons l'education
          </p>
        </div>
      </div>
    </div>
  </div>
</header>
<div class="container">
  <div class="row">
    <!-- Blog Entries Column -->
    <div class="col-md-12 mt-3 left">
      {% for article in article_list %}
      <div class="card mb-4">
        <div class="card-body">
          <h2 class="card-title">{{ article.title }}</h2>
          <p class="card-text text-muted h6">{{ article.author }} | {{ article.created_on}} </p>
          <p class="card-text">{{article.content|slice:":200" }}</p>
          <a href="{% url 'article_detail' article.slug  %}" class="btn btn-primary">En savoir plus &rarr;</a>
        </div>
      </div>
      {% endfor %}
    </div>

  </div>
</div>
{%endblock%}

Avec la balise de template {% extends %}, nous indiquons à Django d'hériter du template base.html. Ensuite, nous remplissons les blocs de contenu du template de base avec du contenu.

Remarquez que nous utilisons la boucle for en HTML, c'est la puissance des templates de Django qui rend le HTML dynamique. La boucle parcourt les article et affiche leur titre, leur date, leur auteur et leur corps, en incluant un lien dans le titre vers l'URL canonique de l'article.

Dans le corps de l'article, nous utilisons également des filtres de modèle pour limiter les mots des extraits à 200 caractères. Les filtres de modèle vous permettent de modifier les variables pour l'affichage et ressemblent à {{ variable | filtre }}.

Exécutez maintenant le serveur et visitez http://127.0.0.1:8000/. Vous verrez la page d'accueil de notre blog.

Maintenant, créons un template HTML pour la vue détaillée de nos articles.

Ensuite, créez un fichier post_detail.html et collez-y le HTML ci-dessous.

{% extends 'base.html' %} {% block content %}

<div class="container">
  <div class="row">
    <div class="col-md-12 card mb-4  mt-3 left  top">
      <div class="card-body">
        <h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
        <p class=" text-muted">{{ article.author }} | {{ article.created_on }}</p>
        <p class="card-text ">{{ object.content | safe }}</p>
      </div>
    </div>
  </div>
</div>

{% endblock content %}

En haut, nous spécifions que ce modèle hérite de base.html Puis nous affichons le corps de notre objet contextuel, que DetailView rend accessible en tant qu'objet.

Maintenant, visitez la page d'accueil et cliquez sur en savoir plus, cela devrait vous rediriger vers la page de détail de l'article.

Conclusion

Nous sommes arrivés à la fin de ce tutoriel. Merci d'avoir suivi jusqu'ici. Ce billet n'est que la partie émergée de l'iceberg compte tenu du nombre de choses que vous pouvez faire avec Django.

Nous avons construit une application de blog de base à partir de rien ! En utilisant l'administration de Django, nous pouvons créer, modifier ou supprimer le contenu et nous avons utilisé les vues basées sur les classes de Django, et à la fin, nous avons créé de magnifiques template pour le rendre.

Si vous êtes bloqué à une étape, reportez-vous à ce dépôt GitHub.

Cette application de blog devrait suffire à vous faire découvrir Django. Si vous voulez aller plus loin, inscrivez-vous à notre prochaine cohorte.