Créer un blog à l'aide de Django, Vue et GraphQL – Real Python

By | mai 24, 2021

Formation gratuite Python

Êtes-vous un utilisateur régulier de Django? Voulez-vous découpler votre back-end et votre front-end, en gérant la persistance des données dans l'API tout en affichant les données dans un cadre côté client comme React ou Vue affiche ces données, dans une application d'une seule page (SPA) dans le navigateur ? Tu es chanceux. Ce tutoriel vous guidera à travers le processus de création d'un back-end de blog Django et d'un front-end Vue, en utilisant GraphQL pour communiquer entre eux.

Les projets sont un moyen efficace d'apprendre et de solidifier des concepts. Ce didacticiel est structuré comme un projet étape par étape afin que vous puissiez apprendre de manière pratique et prendre des pauses au besoin.

Dans ce didacticiel, vous apprendrez à:

  • Traduisez votre Modèles Django dans une API GraphQL
  • Exécutez le Serveur Django et un Application Vue sur votre ordinateur en même temps
  • Administrez vos articles de blog dans le Administrateur Django
  • Consommez une API GraphQL dans Vue pour afficher les données dans le navigateur

Vous pouvez télécharger tout le code source que vous utiliserez pour créer votre application de blog Django en cliquant sur le lien ci-dessous:

Démo: un administrateur de blog Django, une API GraphQL et un frontal Vue

Les applications de blog sont un projet de démarrage courant car elles impliquent des opérations de création, de lecture, de mise à jour et de suppression (CRUD). Dans ce projet, vous utiliserez l'administrateur Django pour faire le gros du CRUD et vous concentrer sur la fourniture d'une API GraphQL pour les données de votre blog.

Voici une démonstration du projet terminé en action:

Ensuite, vous vous assurerez de disposer de toutes les informations générales et outils nécessaires avant de vous lancer dans la création de votre application de blog.

Aperçu du projet

Vous allez créer une petite application de blog avec des fonctionnalités rudimentaires. Les auteurs peuvent écrire de nombreux articles. Les articles peuvent avoir de nombreuses balises et peuvent être publiés ou non.

Vous allez créer le back-end de ce blog dans Django, avec un administrateur pour ajouter du nouveau contenu de blog. Ensuite, vous exposez les données de contenu en tant qu'API GraphQL et utilisez Vue pour afficher ces données dans le navigateur. Vous accomplirez cela en plusieurs étapes de haut niveau:

  1. Configurer le blog Django
  2. Créer l'administrateur du blog Django
  3. Configurer Graphene-Django
  4. Mettre en place django-cors-headers
  5. Configurer Vue.js
  6. Configurer Vue Router
  7. Créer les composants Vue
  8. Récupérez les données

Chaque section fournira des liens vers toutes les ressources nécessaires et vous donnera la possibilité de faire une pause et de revenir au besoin.

Conditions préalables

Vous serez mieux équipé pour ce didacticiel si vous disposez déjà d'une base solide dans certains concepts d'applications Web. Vous devez comprendre le fonctionnement des requêtes et réponses HTTP et des API. Vous pouvez consulter Python et API: un combo gagnant pour la lecture de données publiques pour comprendre les détails de l'utilisation des API GraphQL par rapport aux API REST.

Étant donné que vous utiliserez Django pour créer le back-end de votre blog, vous souhaiterez vous familiariser avec le démarrage d'un projet Django et la personnalisation de l'administrateur Django. Si vous n’avez pas beaucoup utilisé Django auparavant, vous voudrez peut-être également essayer de créer un autre projet uniquement Django. Pour une bonne introduction, consultez Premiers pas avec Django Partie 1: Créer une application Portfolio.

Étant donné que vous utiliserez Vue sur le front-end, une certaine expérience avec JavaScript réactif vous aidera également. Si vous n’avez utilisé qu’un paradigme de manipulation DOM avec un framework tel que jQuery dans le passé, l’introduction de Vue est une bonne base.

La connaissance de JSON est également importante car les requêtes GraphQL sont de type JSON et renvoient des données au format JSON. Vous pouvez en savoir plus sur l'utilisation des données JSON en Python pour une introduction. Vous devrez également installer Node.js pour travailler sur le front-end plus loin dans ce didacticiel.

Étape 1: Configurer le blog Django

Avant d'aller trop loin, vous aurez besoin d'un répertoire dans lequel vous pourrez organiser le code de votre projet. Commencez par en créer un appelé dvg /, abréviation de Django-Vue-GraphQL:

Vous diviserez également complètement le code frontal et le code principal, c'est donc une bonne idée de commencer à créer cette séparation dès le départ. Créer un backend / répertoire dans votre répertoire de projet:

$ backend mkdir /
$ CD backend /

Vous placerez votre code Django dans ce répertoire, complètement isolé du code Vue que vous créerez plus tard dans ce tutoriel.

Installez Django

Vous êtes maintenant prêt à commencer à créer l'application Django. Pour séparer les dépendances de ce projet de vos autres projets, créez un environnement virtuel dans lequel vous installerez les exigences de votre projet. Vous pouvez en savoir plus sur les environnements virtuels dans Python Virtual Environments: A Primer. Le reste du didacticiel suppose que vous exécuterez des commandes liées à Python et Django dans votre environnement virtuel actif.

Maintenant que vous disposez d'un environnement virtuel dans lequel installer les exigences, créez un requirements.txt fichier dans le backend / répertoire et définissez la première exigence dont vous aurez besoin:

Une fois que vous avez enregistré le requirements.txt fichier, utilisez-le pour installer Django:

(venv) $ python -m pip install -r requirements.txt

Vous pourrez maintenant commencer à créer votre projet Django.

Créer le projet Django

Maintenant que Django est installé, utilisez le django-admin commande pour initialiser votre projet Django:

(venv) $ django-admin startproject backend.

Cela crée un manage.py module et un backend paquet dans le backend / répertoire, donc la structure du répertoire de votre projet devrait maintenant ressembler à ceci:

dvg
└── backend
    ├── manage.py
    ├── requirements.txt
    └── backend
        ├── __init__.py
        ├── asgi.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

Ce didacticiel ne couvrira pas ou n’aura pas besoin de tous ces fichiers, mais cela ne fera pas de mal qu’ils soient présents.

Exécuter les migrations Django

Avant d’ajouter quoi que ce soit de spécifique à votre application, vous devez également exécuter l’initialisation de Django migrations. Si vous n’avez pas encore traité de migrations, consultez Django Migrations: A Primer. Exécutez les migrations à l'aide du émigrer commande de gestion:

(venv) $ python manage.py migrer

Vous devriez voir une longue liste de migrations, chacune avec un d'accord après ça:

Opérations à effectuer:
  Appliquer toutes les migrations: admin, auth, contenttypes, sessions
Migrations en cours:
  Application des types de contenu.0001_initial ... OK
  Application de l'auth.0001_initial ... OK
  Application de admin.0001_initial ... OK
  Application de admin.0002_logentry_remove_auto_add ... OK
  Application de admin.0003_logentry_add_action_flag_choices ... OK
  Application des types de contenu.0002_remove_content_type_name ... OK
  Application de l'auth.0002_alter_permission_name_max_length ... OK
  Application de auth.0003_alter_user_email_max_length ... OK
  Application de auth.0004_alter_user_username_opts ... OK
  Application de auth.0005_alter_user_last_login_null ... OK
  Application de auth.0006_require_contenttypes_0002 ... OK
  Application de auth.0007_alter_validators_add_error_messages ... OK
  Application de auth.0008_alter_user_username_max_length ... OK
  Application de auth.0009_alter_user_last_name_max_length ... OK
  Application de auth.0010_alter_group_name_max_length ... OK
  Application de auth.0011_update_proxy_permissions ... OK
  Application de auth.0012_alter_user_first_name_max_length ... OK
  Application des sessions.0001_initial ... OK

Cela créera un fichier de base de données SQLite appelé db.sqlite3 qui stockera également le reste des données de votre projet.

Créer un superutilisateur

Maintenant que vous avez la base de données, vous pouvez créer un superutilisateur. Vous aurez besoin de cet utilisateur pour pouvoir éventuellement vous connecter à l'interface d'administration de Django. Utilisez le créeuperutilisateur commande de gestion pour en créer un:

(venv) $ python manage.py créeuperuser

Vous pourrez utiliser le nom d'utilisateur et le mot de passe que vous avez fournis à cette étape pour vous connecter à l'administrateur Django dans la section suivante.

Résumé de l'étape 1

Maintenant que vous avez installé Django, créé le projet Django, exécuté les migrations Django et créé un super-utilisateur, vous disposez d'une application Django pleinement opérationnelle. Vous devriez maintenant pouvoir démarrer le serveur de développement Django et l'afficher dans votre navigateur. Démarrez le serveur à l'aide du serveur d'exécution commande de gestion, qui écoutera le port 8 000 par défaut:

(venv) $ python manage.py runserver

Maintenant, visitez http: // localhost: 8000 dans votre navigateur. Vous devriez voir la page d'accueil de Django, indiquant que l'installation a fonctionné avec succès. Vous devriez également pouvoir visiter http: // localhost: 8000 / admin, où vous verrez un formulaire de connexion.

Utilisez le nom d'utilisateur et le mot de passe que vous avez créés pour votre super-utilisateur pour vous connecter à l'admin Django. Si tout fonctionne, vous serez redirigé vers le Tableau de bord d'administration Django page. Cette page sera assez vide pour le moment, mais vous la rendrez beaucoup plus intéressante à l'étape suivante.

Étape 2: créer l'administrateur du blog Django

Maintenant que vous avez les bases de votre projet Django en place, vous êtes prêt à commencer à créer une partie de la logique métier de base de votre blog. Dans cette étape, vous allez créer le modèles de données et le configuration administrative pour la création et la gestion du contenu du blog.

Créer l'application de blog Django

Gardez à l'esprit qu'un seul projet Django peut contenir de nombreuses applications Django. Vous devez séparer le comportement de votre blog dans sa propre application Django afin qu'il reste distinct des futures applications que vous intégrez à votre projet. Créez l'application à l'aide du startapp commande de gestion:

(venv) $ blog python manage.py startapp

Cela créera un Blog/ répertoire avec plusieurs fichiers squelettes:

Blog
├── __init__.py
├── admin.py
├── apps.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py

Vous apporterez des modifications et des ajouts à certains de ces fichiers plus tard dans ce didacticiel.

Activer l'application de blog Django

La création d’une application Django ne la rend pas disponible par défaut dans votre projet. Pour vous assurer que le projet connaît votre nouveau Blog application, vous devrez l'ajouter à la liste des applications installées. Mettre à jour le INSTALLED_APPS variable dans backend / settings.py:

INSTALLED_APPS = [[[[
  ...
  "Blog",
]

Cela aidera Django à découvrir des informations sur votre application, telles que les modèles de données et les modèles d'URL qu'elle contient.

Créer les modèles de données du blog Django

Maintenant que Django peut découvrir votre Blog application, vous pouvez créer les modèles de données. Vous allez créer trois modèles pour commencer:

  1. Profil stocke des informations supplémentaires sur les utilisateurs du blog.
  2. Étiqueter représente une catégorie dans laquelle les articles de blog peuvent être regroupés.
  3. Poster stocke le contenu et les métadonnées de chaque article de blog.

Vous allez ajouter chacun de ces modèles à blog / models.py. Tout d'abord, importez les fichiers Django django.db.models module:

de django.db importer des modèles

Chacun de vos modèles héritera de la modèles.Modèle classer.

le Profil Modèle

le Profil modèle aura quelques champs:

  • utilisateur est une association un-à-un à l'utilisateur Django auquel le profil est associé.
  • site Internet est une URL facultative où vous pouvez en savoir plus sur l'utilisateur.
  • bio est un texte de présentation facultatif de la taille d'un tweet pour en savoir plus rapidement sur l'utilisateur.

Vous devrez d'abord importer le Les paramètres module de Django:

de django.conf importer Les paramètres

Puis créez le Profil model, qui devrait ressembler à l'extrait de code suivant:

classer Profil(des modèles.Modèle):
    utilisateur = des modèles.OneToOneField(
        Les paramètres.AUTH_USER_MODEL,
        on_delete=des modèles.PROTÉGER,
    )
    site Internet = des modèles.URLField(Vide=Vrai)
    bio = des modèles.CharField(longueur maximale=240, Vide=Vrai)

    def __str__(soi):
        revenir soi.utilisateur.get_username()

le __str__ la méthode rendra le Profil les objets que vous créez apparaissent de manière plus conviviale sur le site d'administration.

le Étiqueter Modèle

le Étiqueter le modèle n'a qu'un seul champ, Nom, qui stocke un nom court et unique pour la balise. Créer le Étiqueter model, qui devrait ressembler à l'extrait de code suivant:

classer Étiqueter(des modèles.Modèle):
    Nom = des modèles.CharField(longueur maximale=50, unique=Vrai)

    def __str__(soi):
        revenir soi.Nom

De nouveau, __str__ fera le Étiqueter les objets que vous créez apparaissent de manière plus conviviale sur le site d'administration.

le Poster Modèle

le Poster le modèle, comme vous pouvez l'imaginer, est le plus impliqué. Il aura plusieurs champs:

Nom de domaine Objectif
Titre Le titre unique de l'article à afficher aux lecteurs
Sous-titre Un clarificateur facultatif du contenu de l'article pour aider les lecteurs à comprendre s'ils veulent le lire
limace Un identifiant unique et lisible pour la publication à utiliser dans les URL
corps Le contenu du message
Meta Description Une description facultative à utiliser pour les moteurs de recherche comme Google
date créée Un horodatage de la création de l'article
date modifiée Un horodatage de la dernière modification du post
date de publication Un horodatage facultatif lorsque la publication est mise en ligne
publié Si le message est actuellement disponible pour les lecteurs
auteur Une référence au profil de l'utilisateur qui a rédigé le message
Mots clés La liste des balises associées à l'article, le cas échéant

Étant donné que les blogs affichent généralement les messages les plus récents en premier, vous souhaiterez également commande à être par date de publication, avec la plus récente en premier. Créer le Poster model, qui devrait ressembler à l'extrait de code suivant:

classer Poster(des modèles.Modèle):
    classer Meta:
        commande = [[[["-date de publication"]

    Titre = des modèles.CharField(longueur maximale=255, unique=Vrai)
    Sous-titre = des modèles.CharField(longueur maximale=255, Vide=Vrai)
    limace = des modèles.SlugField(longueur maximale=255, unique=Vrai)
    corps = des modèles.Champ de texte()
    Meta Description = des modèles.CharField(longueur maximale=150, Vide=Vrai)
    date créée = des modèles.DateTimeField(auto_now_add=Vrai)
    date modifiée = des modèles.DateTimeField(auto_now=Vrai)
    date de publication = des modèles.DateTimeField(Vide=Vrai, nul=Vrai)
    publié = des modèles.BooleanField(défaut=Faux)

    auteur = des modèles.Clé étrangère(Profil, on_delete=des modèles.PROTÉGER)
    Mots clés = des modèles.ManyToManyField(Étiqueter, Vide=Vrai)

le on_delete = models.PROTECT argument pour auteur garantit que vous ne supprimerez pas accidentellement un auteur qui a encore des articles sur le blog. le ManyToManyField Relation avec Étiqueter vous permet d'associer une publication à zéro ou plusieurs balises. Chaque balise peut être associée à de nombreux articles.

Créer la configuration de l'administrateur du modèle

Maintenant que vos modèles sont en place, vous devez indiquer à Django comment ils doivent être affichés dans l'interface d'administration. Dans blog / admin.py, commencez par importer de Django admin module et vos modèles:

de django.contrib importer admin

de blog.modèles importer Profil, Poster, Étiqueter

Ensuite, créez et enregistrez les classes d'administration pour Profil et Étiqueter, qui n'ont besoin que du maquette spécifié:

@admin.S'inscrire(Profil)
classer ProfileAdmin(admin.ModelAdmin):
    maquette = Profil

@admin.S'inscrire(Étiqueter)
classer TagAdmin(admin.ModelAdmin):
    maquette = Étiqueter

Tout comme le modèle, la classe admin pour Poster est plus impliqué. Les messages contiennent beaucoup d'informations, il est donc utile d'être plus judicieux sur les informations que vous affichez pour éviter d'encombrer l'interface.

Dans la liste de tous les messages, vous spécifiez que Django ne doit afficher que les informations suivantes sur chaque message:

  1. identifiant
  2. Titre
  3. Sous-titre
  4. Limace
  5. Date de publication
  6. Publier le statut

Pour rendre la navigation et la modification des articles plus fluides, vous devez également indiquer au système d'administration Django de prendre les mesures suivantes:

  • Autoriser le filtrage de la liste de publications en fonction des publications publiées ou non publiées.
  • Autoriser le filtrage des publications par date de publication.
  • Autorise la modification de tous les champs affichés, à l'exception de l'ID.
  • Autorisez la recherche de messages à l'aide du titre, du sous-titre, du slug et du corps.
  • Préremplissez le champ de slug en utilisant les champs de titre et de sous-titre.
  • Utilisez la date de publication de tous les articles pour créer une hiérarchie de dates consultable.
  • Afficher un bouton en haut de la liste pour enregistrer les modifications.

Créez et enregistrez le PostAdmin classer:

@admin.S'inscrire(Poster)
classer PostAdmin(admin.ModelAdmin):
    maquette = Poster

    list_display = (
        "identifiant",
        "Titre",
        "Sous-titre",
        "limace",
        "date de publication",
        "publié",
    )
    list_filter = (
        "publié",
        "date de publication",
    )
    list_editable = (
        "Titre",
        "Sous-titre",
        "limace",
        "date de publication",
        "publié",
    )
    champs_recherche = (
        "Titre",
        "Sous-titre",
        "limace",
        "corps",
    )
    prepopulated_fields = 
        "limace": (
            "Titre",
            "Sous-titre",
        )
    
    date_hierarchy = "date de publication"
    save_on_top = Vrai

Vous pouvez en savoir plus sur toutes les options offertes par l'administrateur Django dans Personnaliser l'administrateur Django avec Python.

Créer les migrations de modèles

Django dispose de toutes les informations nécessaires pour administrer et conserver le contenu de votre blog, mais vous devrez d'abord mettre à jour la base de données pour prendre en charge ces changements. Plus tôt dans ce didacticiel, vous avez exécuté les migrations de Django pour ses modèles intégrés. Vous allez maintenant créer et exécuter des migrations pour vos modèles.

Commencez par créer les migrations à l'aide du faire des migrations commande de gestion:

(venv) $ python manage.py makemigrations
Migrations pour 'blog':
        blog / migrations / 0001_initial.py
                - Créer une balise de modèle
                - Créer un profil de modèle
                - Créer un modèle de poste

Cela crée une migration dont le nom est 0001_initial.py par défaut. Exécutez cette migration à l'aide du émigrer commande de gestion:

(venv) $ python manage.py migrer
Opérations à effectuer:
        Appliquer toutes les migrations: admin, auth, blog, contenttypes, sessions
Migrations en cours:
        Application du blog.0001_initial ... OK

Notez que les migrations devraient dire d'accord après le nom de la migration.

Résumé de l'étape 2

Vous avez maintenant tous vos modèles de données en place et vous avez configuré l'administrateur Django pour pouvoir ajouter et modifier ces modèles.

Démarrez ou redémarrez le serveur de développement Django, visitez l'interface d'administration à l'adresse http: // localhost: 8000 / adminet découvrez ce qui a changé. Vous devriez voir des liens vers la liste des balises, des profils et des articles et des liens pour ajouter ou modifier chacun d'entre eux. Essayez d'ajouter et de modifier quelques-uns de chacun pour voir comment l'interface d'administration répond.

Étape 3: Configurer Graphene-Django

À ce stade, vous avez suffisamment terminé le back-end pour que vous pourrait décidez d'aller tête baissée dans la direction de Django. Vous pouvez utiliser le moteur de routage d'URL et de création de modèles de Django pour créer des pages qui montreraient aux lecteurs tout le contenu de l'article que vous créez dans l'administrateur. Au lieu de cela, vous envelopperez le back-end que vous avez créé dans une API GraphQL afin que vous puissiez éventuellement le consommer à partir du navigateur et offrir une expérience côté client plus riche.

GraphQL vous permet de récupérer uniquement les données dont vous avez besoin, ce qui peut être utile par rapport aux réponses très volumineuses qui sont courantes dans les API RESTful. GraphQL offre également plus de flexibilité sur la projection des données, de sorte que vous pouvez souvent récupérer les données de nouvelles manières sans changer la logique du service fournissant l'API GraphQL.

Vous utiliserez Graphene-Django pour intégrer ce que vous avez créé jusqu'à présent dans une API GraphQL.

Installez Graphene-Django

Pour démarrer avec Graphene-Django, ajoutez-le d'abord au fichier des exigences de votre projet:

Ensuite, installez-le à l'aide du fichier d'exigences mis à jour:

(venv) $ python -m pip install -r requirements.txt

Ajouter "graphene_django" au INSTALLED_APPS variable dans votre projet settings.py module pour que Django le trouve:

INSTALLED_APPS = [[[[
  ...
  "Blog",
  "graphene_django",
]

Graphene-Django est maintenant installé et prêt à être configuré.

Configurer Graphene-Django

Pour que Graphene-Django fonctionne dans votre projet, vous devrez configurer quelques éléments:

  1. Mettre à jour settings.py afin que le projet sache où chercher les informations GraphQL.
  2. Ajoutez un modèle d'URL pour servir l'API GraphQL et GraphiQL, l'interface explorable de GraphQL.
  3. Créez le schéma GraphQL pour que Graphene-Django sache comment traduire vos modèles en GraphQL.

Mettre à jour les paramètres de Django

le GRAPHÈNE paramètre configure Graphene-Django pour rechercher à un endroit particulier votre schéma GraphQL. Dirigez-le vers le blog.schema.schema Chemin Python, que vous allez créer sous peu:

GRAPHÈNE = 
  "SCHÉMA": "blog.schema.schema",

Notez que cet ajout peut entraîner Django à produire une erreur d’importation, que vous résolvez lorsque vous créez votre schéma GraphQL.

Ajouter un modèle d'URL pour GraphQL et GraphiQL

Pour permettre à Django de servir le point de terminaison GraphQL et l'interface GraphiQL, vous allez ajouter un nouveau modèle d'URL à backend / urls.py. Vous pointerez l'URL vers Graphene-Django GraphQLView. Étant donné que vous n’utilisez pas les fonctionnalités de protection contre la falsification des demandes intersites (CSRF) du moteur de modèles Django, vous devrez également importer les fichiers de Django csrf_exempt décorateur pour marquer la vue comme exempte de la protection CSRF:

de django.views.decorators.csrf importer csrf_exempt
de graphene_django.views importer GraphQLView

Ensuite, ajoutez le nouveau modèle d'URL au urlpatterns variable:

urlpatterns = [[[[
    ...
    chemin("graphql", csrf_exempt(GraphQLView.as_view(graphiql=Vrai))),
]

le graphiql = Vrai L'argument indique à Graphene-Django de rendre l'interface GraphiQL disponible.

Créer le schéma GraphQL

Vous allez maintenant créer le schéma GraphQL, qui devrait ressembler à la configuration d'administration que vous avez créée précédemment. Le schéma se compose de plusieurs classes qui sont chacune associées à un modèle Django particulier et une pour spécifier comment résoudre quelques types importants de requêtes dont vous aurez besoin dans le front-end.

Créer un nouveau schema.py module dans le Blog/ annuaire. Importer Graphene-Django DjangoObjectType, votre Blog modèles, et le Django Utilisateur maquette:

de django.conf importer Les paramètres
de graphène_django importer DjangoObjectType

de Blog importer des modèles

Créez une classe correspondante pour chacun de vos modèles et le Utilisateur maquette. Ils devraient chacun avoir un nom qui se termine par Taper car chacun représente un type GraphQL. Vos cours devraient ressembler à ce qui suit:

classer Type d'utilisateur(DjangoObjectType):
    classer Meta:
        maquette = Les paramètres.AUTH_USER_MODEL

classer AuthorType(DjangoObjectType):
    classer Meta:
        maquette = des modèles.Profil

classer Type de poste(DjangoObjectType):
    classer Meta:
        maquette = des modèles.Poster

classer TagType(DjangoObjectType):
    classer Meta:
        maquette = des modèles.Étiqueter

Vous devrez créer un Mettre en doute classe qui hérite de graphène.ObjectType. Cette classe rassemblera toutes les classes de types que vous avez créées et vous y ajouterez des méthodes pour indiquer les façons dont vos modèles peuvent être interrogés. Vous devrez importer graphène premier:

le Mettre en doute la classe est composée d'un certain nombre d'attributs qui sont soit graphène.Liste ou alors graphène.. Vous utiliserez graphène. si la requête doit renvoyer un seul élément et graphène.Liste s'il renverra plusieurs articles.

Pour chacun de ces attributs, vous allez également créer une méthode pour résoudre la requête. Vous résolvez une requête en prenant les informations fournies dans la requête et en renvoyant le jeu de requêtes Django approprié en réponse.

La méthode de chaque résolveur doit commencer par résoudre_, et le reste du nom doit correspondre à l'attribut correspondant. À titre d'exemple, la méthode pour résoudre le jeu de requêtes pour le Tous les messages l'attribut doit être nommé resolver_all_posts.

Vous allez créer des requêtes pour obtenir:

  • Tous les articles
  • Un auteur avec un nom d'utilisateur donné
  • Un message avec une limace donnée
  • Tous les articles d'un auteur donné
  • Tous les articles avec une balise donnée

Créer le Mettre en doute classe maintenant. Il devrait ressembler à l'extrait de code suivant:

classer Mettre en doute(graphène.Type d'objet):
    Tous les messages = graphène.Lister(Type de poste)
    author_by_username = graphène.Domaine(AuthorType, Nom d'utilisateur=graphène.Chaîne())
    post_by_slug = graphène.Domaine(Type de poste, limace=graphène.Chaîne())
    posts_by_author = graphène.Lister(Type de poste, Nom d'utilisateur=graphène.Chaîne())
    posts_by_tag = graphène.Lister(Type de poste, étiqueter=graphène.Chaîne())

    def resolver_all_posts(racine, Info):
        revenir (
            des modèles.Poster.objets.prefetch_related("Mots clés")
            .select_related("auteur")
            .tout()
        )

    def resolution_author_by_username(racine, Info, Nom d'utilisateur):
        revenir des modèles.Profil.objets.select_related("utilisateur").obtenir(
            user__username=Nom d'utilisateur
        )

    def resolution_post_by_slug(racine, Info, limace):
        revenir (
            des modèles.Poster.objets.prefetch_related("Mots clés")
            .select_related("auteur")
            .obtenir(limace=limace)
        )

    def resolution_posts_by_author(racine, Info, Nom d'utilisateur):
        revenir (
            des modèles.Poster.objets.prefetch_related("Mots clés")
            .select_related("auteur")
            .filtre(author__user__username=Nom d'utilisateur)
        )

    def resol_posts_by_tag(racine, Info, étiqueter):
        revenir (
            des modèles.Poster.objets.prefetch_related("Mots clés")
            .select_related("auteur")
            .filtre(tags__nom__iexact=étiqueter)
        )

Vous avez maintenant tous les types et résolveurs pour votre schéma, mais rappelez-vous que le GRAPHÈNE la variable sur laquelle vous avez créé pointe blog.schema.schema. Créer un schéma variable qui enveloppe votre Mettre en doute classe dans graphène.Schema pour tout lier:

schéma = graphène.Schéma(mettre en doute=Mettre en doute)

Cette variable correspond au "blog.schema.schema" valeur que vous avez configurée pour Graphene-Django plus tôt dans ce didacticiel.

Résumé de l'étape 3

Vous avez étoffé le modèle de données de votre blog, et maintenant vous avez également enveloppé votre modèle de données avec Graphene-Django pour servir ces données en tant qu'API GraphQL.

Exécutez le serveur de développement Django et visitez http: // localhost: 8000 / graphql. Vous devriez voir l'interface GraphiQL avec du texte commenté qui explique comment utiliser l'outil.

Élargir le Docs section en haut à droite de l'écran et cliquez sur requête: requête. Vous devriez voir chacune des requêtes et types que vous avez configurés dans votre schéma.

Si vous n'avez pas encore créé de contenu de blog de test, faites-le maintenant. Essayez la requête suivante, qui devrait renvoyer une liste de tous les messages que vous avez créés:


  Tous les messages 
    Titre
    Sous-titre
    auteur 
      utilisateur 
        Nom d'utilisateur
      
    
    Mots clés 
      Nom
    
  

La réponse doit renvoyer une liste de messages. La structure de chaque publication doit correspondre à la forme de la requête, comme dans l'exemple suivant:

{
  "Les données": 
    "Tous les messages": [[[[
      
        "Titre": "Le grand débat de Coney Island",
        "Sous-titre": «Américain ou Lafayette?,
        "auteur": 
          "utilisateur": 
            "Nom d'utilisateur": "coney15land"
          
        ,
        "Mots clés": [[[[
          
            "Nom": "aliments"
          ,
          
            "Nom": "Coney Island"
          
        ]
      
    ]
  
}

Si vous avez enregistré certains messages et que vous les voyez dans la réponse, vous êtes prêt à continuer.

Étape 5: Configurer Vue.js

Vous utiliserez Vue comme interface pour votre blog. Pour configurer Vue, vous allez créer le projet Vue, installer quelques plugins importants et exécuter le serveur de développement Vue pour vous assurer que votre application et ses dépendances fonctionnent correctement ensemble.

Créer le projet Vue

Tout comme Django, Vue fournit un interface de ligne de commande pour créer un projet sans repartir totalement de zéro. Vous pouvez associer cela à celui de Node npx commande pour amorcer des commandes basées sur JavaScript que d'autres ont publiées. En utilisant cette approche, vous n'aurez pas besoin d'installer manuellement la variété de dépendances individuelles dont vous avez besoin pour faire fonctionner un projet Vue. Utiliser npx pour créer votre projet Vue maintenant:

$ CD / chemin / vers / dvg /
$ npx @ vue / cli crée un frontend - par défaut
...
🎉 Frontend du projet créé avec succès.
...
$ CD l'extrémité avant/

Cela créera un l'extrémité avant/ répertoire à côté de votre existant backend / répertoire, installez un certain nombre de dépendances JavaScript et créez des fichiers squelettes pour l'application.

Installer les plugins Vue

Vous aurez besoin de quelques plugins pour que Vue effectue le routage approprié du navigateur et interagisse avec votre API GraphQL. Ces plugins affectent parfois vos fichiers, il est donc bon de les installer vers le début afin qu’ils ne remplacent rien, puis de les configurer plus tard. Installez les plugins Vue Router et Vue Apollo, en choisissant les options par défaut lorsque vous y êtes invité:

$ npx @ vue / cli ajouter un routeur
$ npx @ vue / cli ajouter apollo

Ces commandes prendront un certain temps pour installer les dépendances, et elles ajouteront ou modifieront certains des fichiers du projet pour configurer et installer chaque plugin dans votre projet Vue.

Résumé de l'étape 5

Vous devriez maintenant pouvoir exécuter le serveur de développement Vue:

Vous avez maintenant votre application Django en cours d'exécution à http: // localhost: 8000 et votre application Vue fonctionnant à http: // localhost: 8080.

Visite http: // localhost: 8080 dans votre navigateur. Vous devriez voir la page d'accueil de Vue, qui indique que vous avez tout installé avec succès. Si vous voyez la page d’accueil, vous êtes prêt à commencer à créer certains de vos propres composants.

Étape 6: Configurer Vue Router

Une partie importante des applications côté client consiste à gérer le routage sans avoir à faire de nouvelles requêtes au serveur. Une solution courante pour cela dans Vue est le plugin Vue Router, que vous avez installé précédemment. Vous utiliserez Vue Router au lieu des balises d'ancrage HTML normales pour créer un lien vers différentes pages de votre blog.

Créer des itinéraires

Maintenant que vous avez installé Vue Router, vous devez configurer Vue pour utiliser Vue Router. Vous devrez également configurer Vue Router avec les chemins d'URL qu'il doit acheminer.

Créer un router.js module dans le src / annuaire. Ce fichier contiendra toute la configuration sur les URL mappées vers quels composants Vue. Commencez par importer Vue et Vue Router:

importer Vue de 'vue'
importer VueRouter de 'vue-router'

Ajoutez les importations suivantes, qui correspondent chacune à un composant que vous allez créer sous peu:

importer Poster de '@ / components / Post'
importer Auteur de '@ / components / Auteur'
importer PostsByTag de '@ / components / PostsByTag'
importer Tous les messages de '@ / components / AllPosts'

Enregistrez le plugin Vue Router:

Vous allez maintenant créer la liste des itinéraires. Chaque itinéraire a deux propriétés:

  1. chemin est un modèle d'URL qui contient éventuellement des variables de capture similaires aux modèles d'URL Django.
  2. composant est le composant Vue à afficher lorsque le navigateur navigue vers une route correspondant au modèle de chemin.

Ajoutez ces itinéraires en tant que itinéraires variable. Ils devraient ressembler à ce qui suit:

const itinéraires = [[[[
   chemin: '/ author /: nom d'utilisateur', composant: Auteur ,
   chemin: '/ post /: limace', composant: Poster ,
   chemin: '/ tag /: tag', composant: PostsByTag ,
   chemin: '/', composant: Tous les messages ,
]

Créer une nouvelle instance de VueRouter et exportez-le depuis le router.js module pour que d'autres modules puissent l'utiliser:

const routeur = Nouveau VueRouter(
  itinéraires: itinéraires,
  mode: 'l'histoire',
)
exportation défaut routeur

Vous importerez le routeur variable dans un autre module de la section suivante.

Installez le routeur

Au sommet de src / main.js, importez le routeur à partir du module que vous avez créé dans la section précédente:

importer routeur de '@ / routeur'

Ensuite, passez le routeur à l'instance Vue:

Ceci termine la configuration de Vue Router.

Step 6 Summary

You’ve created the routes for your front end, which map a URL pattern to the component that will show up at that URL. The routes won’t work just yet because they point to components that don’t yet exist. You’ll create these components in the next step.

Step 7: Create the Vue Components

Now that you’ve got Vue up and running with routes that will go to your components, you can start creating the components that will eventually display data from the GraphQL endpoint. At the moment, you’ll just make them display some static content. The table below describes the components you’ll create:

Component Displays
AuthorLink A link to a given author’s page (used in Post et PostList)
PostList A given list of blog posts (used in AllPosts, Auteur, and PostsByTag)
AllPosts A list of all posts, with the most recent first
PostsByTag A list of posts associated with a given tag, with the most recent first
Post The metadata and content for a given post
Auteur Information about an author and a list of posts they’ve written

You’ll update these components with dynamic data in the next step.

le PostList Component

le PostList component accepts a posts prop, whose structure corresponds to the data about posts in your GraphQL API. The component also accepts a Boolean showAuthor prop, which you’ll set to faux on the author’s page because it’s redundant information. The component should display the following features:

  • The title and subtitle of the post, linking them to the post’s page
  • A link to the author of the post using AuthorLink (if showAuthor is vrai)
  • The date the post was published
  • The meta description for the post
  • The list of tags associated with the post

Create a PostList.vue SFC in the src/components/ directory. The component template should look like the following:

<template>
  <div>
    <ol class="post-list">
      <li class="post" v-for="post in publishedPosts" :key="post.title">
          <span class="post__title">
            <router-link
              :to="`/post/$post.slug`"
            > post.title :  post.subtitle </router-link>
          </span>
          <span v-if="showAuthor">
            par <AuthorLink :author="post.author" />
          </span>
          <div class="post__date"> displayableDate(post.publishDate) </div>
        <p class="post__description"> post.metaDescription </p>
        <ul>
          <li class="post__tags" v-for="tag in post.tags" :key="tag.name">
            <router-link :to="`/tag/$tag.name`"># tag.name </router-link>
          </li>
        </ul>
      </li>
    </ol>
  </div>
</template>

le PostList component’s JavaScript should look like the following:

<script>
importer AuthorLink de '@/components/AuthorLink'

exportation défaut 
  name: 'PostList',
  components: 
    AuthorLink,
  ,
  props: 
    posts: 
      type: Array,
      required: vrai,
    ,
    showAuthor: 
      type: Boolean,
      required: faux,
      défaut: vrai,
    ,
  ,
  computed: 
    publishedPosts () 
      revenir this.posts.filter(Publier => Publier.published)
    
  ,
  methods: 
    displayableDate (date) 
      revenir new Intl.DateTimeFormat(
        'en-US',
         dateStyle: 'full' ,
      ).format(new Date(date))
    
  ,

</script>

le PostList component receives its data as a prop instead of using GraphQL directly.

You can add some optional CSS styling to make the list of posts a bit more readable once they’re rendered:

<style>
.post-list 
  list-style: none;


.Publier 
  border-bottom: 1px solid #ccc;
  rembourrage en bas: 1rem;


.post__title 
  font-size: 1.25rem;


.post__description 
  color: #777;
  font-style: italic;


.post__tags 
  list-style: none;
  font-weight: bold;
  font-size: 0.8125rem;

</style>

These styles add some spacing, remove some clutter, and differentiate different pieces of information to help with scannability.

le AllPosts Component

The next component you’ll create is a list of all the posts on the blog. It needs to display two pieces of information:

  1. A Recent Posts heading
  2. The list of posts, using PostList

Create the AllPosts.vue SFC in the src/components/ directory. It should look like the following:

<template>
  <div>
    <h2>Recent posts</h2>
    <PostList v-if="allPosts" :posts="allPosts" />
  </div>
</template>

<script>
importer PostList de '@/components/PostList'

exportation défaut 
  name: 'AllPosts',
  components: 
    PostList,
  ,
  data () 
    revenir 
        allPosts: nul,
    
  ,

</script>

You’ll populate the allPosts variable dynamically with a GraphQL query later in this tutorial.

le PostsByTag Component

le PostsByTag component is very similar to the AllPosts component. The heading text differs, and you’ll query for a different set of posts in the next step.

Create the PostsByTag.vue SFC in the src/components/ directory. It should look like the following:

<template>
  <div>
    <h2>Posts in # $route.params.tag </h2>
    <PostList :posts="posts" v-if="posts" />
  </div>
</template>

<script>
importer PostList de '@/components/PostList'

exportation défaut 
  name: 'PostsByTag',
  components: 
    PostList,
  ,
  data () 
    revenir 
      posts: nul,
    
  ,

</script>

You’ll populate the posts variable with a GraphQL query later in this tutorial.

le Auteur Component

le Auteur component acts as an author’s profile page. It should display the following information:

  • A heading with the author’s name
  • A link to the author’s website, if provided
  • The author’s biography, if provided
  • The list of posts by the author, with showAuthor set to faux

Create the Author.vue SFC in the src/components/ directory now. It should look like the following:

<template>
  <div v-if="author">
    <h2> displayName </h2>
    <une
      :href="author.website"
      target="_blank"
      rel="noopener noreferrer"
    >Site Internet</une>
    <p> author.bio </p>

    <h3>Posts by  displayName </h3>
    <PostList :posts="author.postSet" :showAuthor="false" />
  </div>
</template>

<script>
importer PostList de '@/components/PostList'

exportation défaut 
  name: 'Author',
  components: 
    PostList,
  ,
  data () 
    revenir 
      author: nul,
    
  ,
  computed: 
    displayName () 
      revenir (
        this.author.user.firstName &&
        this.author.user.lastName &&
        ''$this.author.user.firstName $this.author.user.lastName''
      ) ,
  ,

</script>

You’ll populate the author variable dynamically with a GraphQL query later in this tutorial.

le Post Component

Just like the data model, the Post component is the most interesting because it has the responsibility of displaying all the post’s information. The component should display the following information about the post:

  • Title and subtitle, as a heading
  • Author, as a link using AuthorLink
  • Publication date
  • Meta description
  • Content body
  • List of associated tags, as links

Because of your data modeling and component architecture, you may be surprised at how little code this requires. Create the Post.vue SFC in the src/components/ directory. It should look like the following:

<template>
  <div class="post" v-if="post">
      <h2> post.title :  post.subtitle </h2>
      Par <AuthorLink :author="post.author" />
      <div> displayableDate(post.publishDate) </div>
    <p class="post__description"> post.metaDescription </p>
    <article>
       post.body 
    </article>
    <ul>
      <li class="post__tags" v-for="tag in post.tags" :key="tag.name">
        <router-link :to="`/tag/$tag.name`"># tag.name </router-link>
      </li>
    </ul>
  </div>
</template>

<script>
importer AuthorLink de '@/components/AuthorLink'

exportation défaut 
  name: 'Post',
  components: 
    AuthorLink,
  ,
  data () 
    revenir 
      Publier: nul,
    
  ,
  methods: 
    displayableDate (date) 
      revenir new Intl.DateTimeFormat(
        'en-US',
         dateStyle: 'full' ,
      ).format(new Date(date))
    
  ,

</script>

You’ll populate the Publier variable dynamically with a GraphQL query later in this tutorial.

le Appli Component

Before you can see the outcomes of your labor, you need to update the Appli component that your Vue setup command created. Instead of showing the Vue splash page, it should show the AllPosts component.

Open the App.vue SFC in the src/ directory. You can delete all the content inside it because you’ll need to replace it with code that displays the following features:

  • A heading with the title of your blog that links to the home page
  • , a Vue Router component that renders the right component for the current route

Votre Appli component should look like the following:

<template>
    <div id="app">
        <header>
          <router-link à="/">
            <h1>Awesome Blog</h1>
          </router-link>
        </header>
        <router-view />
    </div>
</template>

<script>
exportation défaut 
  name: 'App',

</script>

You can also add some optional CSS styling to polish up the display a bit:

<style>
* 
  margin: 0;
  padding: 0;


body 
  margin: 0;
  padding: 1.5rem;


* + * 
  margin-top: 1.5rem;


#appli 
  margin: 0;
  padding: 0;

</style>

These styles give a bit of breathing room to most elements on the page and remove the space around the whole page that most browsers add by default.

Step 7 Summary

If you haven’t used Vue much before, this step might have been a lot to digest. You’ve reached an important milestone, though. You have a working Vue application, complete with routes and views ready to display data.

You can confirm your application is working by starting the Vue development server and visiting http://localhost:8080. You should see the title of your blog and a Recent Posts heading. If you do, then you’re ready to take on the final step, where you’ll use Apollo to query your GraphQL API to bring the front end and back end together.

Step 8: Fetch the Data

Now that you’ve got everything prepped for displaying data when it’s available, it’s time to fetch that data from your GraphQL API.

Apollo makes querying GraphQL APIs more convenient. The Vue Apollo plugin you installed earlier integrates Apollo into Vue, making it that much more convenient to query GraphQL from within your Vue project.

Configure Vue Apollo

Vue Apollo is mostly configured out of the box, but you’ll need to tell it the right endpoint to query. You may also want to turn off the WebSocket connection it tries to use by default because this generates noise in the Network and Console tabs of your browser. Edit the apolloProvider definition in the src/main.js module to specify the httpEndpoint et wsEndpoint properties:

new Vue(
  ...
  apolloProvider: createProvider(
    httpEndpoint: 'http://localhost:8000/graphql',
    wsEndpoint: nul,
  ),
  ...
)

Now you’re ready to start adding the queries to populate your pages. You’ll do this by adding a created() function to several of your SFCs. created() is a special Vue lifecycle hook that executes when a component is about to render on the page. You can use this hook to query for the data you want to render so that it becomes available as your component renders. You’ll create a query for the following components:

  • Post
  • Auteur
  • PostsByTag
  • AllPosts

You can start by creating the Post query.

le Post Query

The query for an individual post accepts the slug of the desired post. It should return all the necessary pieces of information to display the post information and content.

You’ll use the $apollo.query helper and the gql helper to build the query in the Post component’s created() function, ultimately using the response to set the component’s Publier so it can be rendered. created() should look like the following:

<script>
  ...
  async created () {
    const Publier = await this.$apollo.query({
        query: gql`query ($slug: String!) 
                                        postBySlug(slug: $slug) 
                                                Titre
                                                subtitle
                                                publishDate
                                                metaDescription
                                                slug
                                                body
                                                author 
                                                        user 
                                                                username
                                                                firstName
                                                                lastName
                                                        
                                                
                                                tags 
                                                        name
                                                
                                        
                                `,
        variables: 
          slug: this.$route.params.slug,
        ,
    })
    this.Publier = Publier.data.postBySlug
  },
  ...
</script>

This query pulls in most of the data about the post and its associated author and tags. Notice that the $slug placeholder is used in the query, and the variables property passed to $apollo.query is used to populate the placeholder. le slug property matches the $slug placeholder by name. You’ll see this pattern again in some of the other queries.

le Auteur Query

Whereas in the query for Post you fetched the single post’s data and some nested data about the author, in the Auteur query you’ll need to fetch the author data and the list of all posts by the author.

The author query accepts the username of the desired author and should return all the necessary pieces of information to display the author and their list of posts. It should look like the following:

<script>
  ...
  async created () {
    const user = await this.$apollo.query({
      query: gql`query ($username: String!) 
                                authorByUsername(username: $username) 
                                        website
                                        bio
                                        user 
                                                firstName
                                                lastName
                                                username
                                        
                                        postSet 
                                                Titre
                                                subtitle
                                                publishDate
                                                published
                                                metaDescription
                                                slug
                                                tags 
                                                        name
                                                
                                        
                                
                        `,
      variables: 
        username: this.$route.params.username,
      ,
    })
    this.author = user.data.authorByUsername
  },
  ...
</script>

This query uses postSet, which might look familiar if you’ve done some Django data modeling in the past. The name “post set” comes from the reverse relationship Django creates for a ForeignKey field. In this case, the post has a foreign key relationship to its author, which has a reverse relationship with the post called post_set. Graphene-Django has automatically exposed this as postSet in the GraphQL API.

le PostsByTag Query

The query for PostsByTag should feel pretty similar to the first queries you created. This query accepts the desired tag and returns the list of matching posts. created() should look like the following:

<script>
  ...
  async created () {
    const posts = await this.$apollo.query({
      query: gql`query ($tag: String!) 
                                postsByTag(tag: $tag) 
                                        Titre
                                        subtitle
                                        publishDate
                                        published
                                        metaDescription
                                        slug
                                        author 
                                                user 
                                                        username
                                                        firstName
                                                        lastName
                                                
                                        
                                        tags 
                                                name
                                        
                                
                        `,
      variables: 
        tag: this.$route.params.tag,
      ,
    })
    this.posts = posts.data.postsByTag
  },
  ...
</script>

You might notice that some pieces of each query look pretty similar to one another. Although it won’t be covered in this tutorial, you can use GraphQL fragments to reduce duplication in your query code.

le AllPosts Query

The query for AllPosts doesn’t require any input information and returns the same set of information as the PostsByTag query. It should look like the following:

<script>
  ...
  async created () {
    const posts = await this.$apollo.query({
      query: gql`query 
                                allPosts 
                                        Titre
                                        subtitle
                                        publishDate
                                        published
                                        metaDescription
                                        slug
                                        author 
                                                user 
                                                        username
                                                        firstName
                                                        lastName
                                                
                                        
                                        tags 
                                                name
                                        
                                
                        `,
    })
    this.allPosts = posts.data.allPosts
  },
  ...
</script>

This is the last query for now, but you should revisit the last couple of steps to let them sink in. If you want to add new pages with new views of your data in the future, it’s a matter of creating a route, a component, and a query.

Step 8 Summary

Now that each component is fetching the data it needs to display, you’ve arrived at a functioning blog. Run the Django development server and the Vue development server. Visit http://localhost:8080 and browse through your blog. If you can see authors, posts, tags, and the content of a post in your browser, you’re golden!

Prochaines étapes

You started by creating a Django blog back end to administer, persist, and serve the data for a blog. Then you created a Vue front end to consume and display that data. You made the two communicate with GraphQL using Graphene and Apollo.

You may already be wondering what you can do next. To further validate that your blog is working as expected, you could try the following:

  • Add more users and posts to see them split up by author.
  • Make some posts unpublished to confirm that they don’t show up on the blog.

If you’re feeling confident and adventurous with what you have going, you can also take this system of yours even further:

  • Expand your data model to create new behavior in your Django blog.
  • Create new queries to provide interesting views on your blog’s data.
  • Explore GraphQL mutations to write data in addition to reading it.
  • Add CSS to your single-file components to make the blog more eye-catching.

The data modeling and component architecture you’ve put together is remarkably extensible, so take it as far as you like!

If you want to make your Django application ready for prime time, read Deploying Django + Python3 + PostgreSQL to AWS Elastic Beanstalk or Development and Deployment of Django on Fedora. You can use Amazon Web Services or something like Netlify to deploy your Vue project as well.

Conclusion

You’ve seen how you can use GraphQL for building typed, flexible views of your data. You can use these same techniques on an existing Django application you’ve built or one you plan to build. Like other APIs, you can use yours in most any client-side framework as well.

In this tutorial, you learned how to:

  • Build the Django blog data model et admin interface
  • Wrap your data model in a GraphQL API using Graphene-Django
  • Create and route to separate Vue components for each view of the data
  • Query the GraphQL API dynamically to populate your Vue components using Apollo

You covered a lot of ground, so try to identify some new ways to use these concepts in different contexts to solidify your learning. Happy coding, and happy blogging!

You can download the complete source code for this project by clicking the link below:

[ad_2]