-
Notifications
You must be signed in to change notification settings - Fork 1
Tuto django et uniformisation
Il y a trois éléments à distinguer quand on manipule Django avec REST, le modèle, le serializer, et la vue. Il faut ensuite penser à modifier les urls.
Le modèle sert à donner a Django la structure de nos ressources. Il se charge tout seul de manipuler la base de donnée. Le modèle est la classe principale de la ressource. Sur le modèle on placera :
- Les propriétés de la ressource (pas besoin de définir un id, il existe par défaut sur django)
- Éventuellement Des fonctions de manipulation de la ressource, et de ses attributs
- Les droits de la ressource (voir le paragraphe DRYPermission)
Le schéma de base d'une ressource est :
from django.db import models
class MonModel(models.Model):
################################################################
# CONSTANTS #
################################################################
# Liste de constantes à utiliser en cas de choix, par exemple ici, le champ type
TYPE_1 = 0
TYPE_2 = 2
################################################################
# FIELDS #
################################################################
# Liste des champs de l'objet
name = models.CharField(max_length=254)
group = models.ForeignKey('MonAutreModele')
type = models.PositiveSmallIntegerField(default=TYPE_0)
################################################################
# PERMISSIONS #
################################################################
def has_object_read_permission(self, request):
return True
@staticmethod
def has_read_permission(request):
return True
def has_object_write_permission(self, request):
return True
@staticmethod
def has_write_permission(request):
return True
Il se charge d'effectuer la transformation : représentation <=> modèle django Ici, il se chargera de transformer une ressource django en json pour l'envoi, et convertir du json en ressource django pour modifier la base de donnée. Cette classe est souvent très vide puisqu'il existe une base RESTFramework qui permet de créer automatiquement le serializer à partir du modèle Django. Important, il ne peut pas automatiquement décrire une relation ! Il faut alors lui expliquer comment il est censé traduire une relation, en code JSON. Le plus souvent, il s'agit du cas OneToMany, où il suffit de lui dire de donner la clé primaire de l'objet pointé.
Exemple type d'un sérializer :
from rest_framework import serializers
from sigma_core.models.monmodel import MonModel
from sigma_core.models.monmodel import MonAutreModel
class MonSerializer(serializers.ModelSerializer):
class Meta:
model = MonModel
# On precise que la relation MonModel.group doit se traduire par la clef primaire de l'objet pointe
group = serializers.PrimaryKeyRelatedField(queryset=MonAutreModel.objects.all())
Une vue est une fonction qui gère une requête, et renvoie la réponse appropriée. De manière générale, le protocole de communication étant standardisé (REST), on peut laisser le REST-framework faire les choses pour nous à l'aide du ModelViewset. A partir d'un modèle, et d'un serializer, il crée automatiquement les vues correspondantes au diverses actions.
Les diverses actions sont :
- Actions de lecture (read)
-
- La récupération d'une liste d'élement (list)
-
- La récupération d'un élément en particulier (retreive)
- Actions d'écriture (write)
-
- La création (create)
-
- L'édition d'un élément en particulier (update)
-
- La suppression d'un élement particulier (destroy)
On distingue aussi les actions globales (list, create) qui ne prennent pas de paramètre, et les actions objects (retreive, update, destroy) qui prennent un identifieur (appelé
pk
) de ressource.
- La suppression d'un élement particulier (destroy)
On distingue aussi les actions globales (list, create) qui ne prennent pas de paramètre, et les actions objects (retreive, update, destroy) qui prennent un identifieur (appelé
Il est possible de créer une route supplémentaire en utilisant un décorateur. On en utilisant @detail_route on créer une route qui prend un paramètre, et en utilisant @list_route, une route qui ne prend aucun paramètre. Ces deux décorateurs prennent entre autre un argument, la méthode HTTP correspondant à la route, soit get, soit post. (ne pas confondre la méthode HTTP qui définie comment passer les données, et l'action qui définie qu'en faire) Le nom de la vue est alors le nom de la fonction. En pratique, dans une telle fonction, on récupère un ou des objets selon un critère, on sérialise le/les objets, puis on les retourne dans une Reponse.
Important, la gestion des droits se fait de manière automatisée en utilisant DRYPermission. Il faut pour cela préciser à la vue d'utiliser DRYPermission. Je parlerais de la gestion des droits dans une autre partie.
Exemple type d'une vue :
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from dry_rest_permissions.generics import DRYPermissions
from sigma_core.models.monmodel import MonModel
from sigma_core.serializers.monserializer import MonSerializer
class MaViewset(viewsets.ModelViewSet):
queryset = MonModel.objects.all()
serializer_class = MonSerializer
permission_classes = [IsAuthenticated, DRYPermissions]
@detail_route(methods=['get'])
def objet_special(self, request, pk=None):
# [...]
# truc type :
data = [...]
serializer = UnSerializer(data)
return Response(serializer.data)
# s'il manque des droits
return Response("Pas possible", status=status.HTTP_403_FORBIDDEN)
## Les URLs
Une fois la vue créée, il faut dire a Django de faire correspondre une url avec une vue. Encore une fois, grace à REST qui standardise le tout, le processus est simplifié. Il suffit de lui donner une Viewset et il va générer automatiquement les url correspondantes.
Dans le cas d'une action particulière créée avec @detail_route ou @list_route dans un viewset mavue, l'url correspondant est alors `mavue/monaction` ou `/?pk/mavue`