Django Rest Framework – Import cyclic, comment s’en sortir

Je vais être franc, je ne suis pas sûr de proposer une solution élégante à ce problème, mais je n’ai pas réussi à trouver mieux.

Pour illustrer le problème il suffit de prendre le cas d’un model Utilisateur et d’un model Article.

On souhaite créer un UserSerializer qui inclut tous les Articles de l’auteur et un ArticleSerializer qui inclut l’auteur de l’article. Personellement j’aime bien séparer mes serializers, avec dans ce cas 2 fichiers : serializers/users.py et serializers/articles.py

# serializers/users.py
from .articles import ArticleSerializer
 
class UserSerializer(ModelSerializer):
    articles = ArticleSerializer(many=True)
    class Meta:
        model = User
        fields = ('__all__')
 
# serializers/articles.py
from .users import UserSerializer
 
class ArticleSerializer(ModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Article
        fields = ('__all__')

Cependant, avec ce système vous allez avoir une importation cyclic pour la simple et bonne raison que Python va exécuter le code des fichiers inclus lors de l’inclusions, et donc par conséquence faire les importations des fichiers importés !

La solution la plus élégante trouvée est d’utiliser une importation locale en utilisant SerializerMethodField :

# serializers/users.py
class UserSerializer(ModelSerializer):
    articles = serializers.SerializerMethodField()
 
    def get_articles(self, o):
        from .articles import ArticleSerializer # On import ici, ce qui évite une inclusion circulaire
        return ArticleSerializer(o.articles).data
 
    class Meta:
        model = User
        fields = ('__all__')

Donc, si vous avez des solutions plus propres, plus élégantes, et bien je suis preneur !

Aymeric DERBOIS

J'ai 27 ans et je suis développeur. Je travail la plupart du temps sur des techno web, mais pas que. Étant à l'affût des nouveautés, j'adore découvrir tout et n'importe quoi dans l'informatique. Je suis amoureux de CakePHP et j'utilise au quotidien Django. Je suis très ouvert d'esprit :). J'aime bien utiliser AngularJS aussi de temps à autre pour faire du front. Au quotidien j'utilise Fedora/Ubuntu pour le desktop et CentOS pour mes serveurs. Par ailleurs je maîtrise le C/C++/Python/PHP/...

More Posts - Website

Follow Me:
Twitter

2 réponses pour “Django Rest Framework – Import cyclic, comment s’en sortir”

  1. paulo13 juin 2019 à 21 h 14 minRépondre

    pourquoi ne pas utiliser __all__ dans le fichier init?

  2. Aymeric DERBOIS14 juin 2019 à 13 h 51 minRépondre

    Je ne suis pas certain de l’utilisation de __all__ dans le fichier __init__.py change grand chose. Normalement on utilise __all__ pour définir ce qui sera importé quand on fait un from .mymodule import *

    Mais de toute façon, en relisant ce post aujourdh’ui je me rend compte que le vrai problème n’est pas tant l’import cyclique, mais le design des serializers qui est cyclique.

    Ce post ayant 3 ans, il faudrait que je prenne le temps de repasser sur les vieux articles que j’ai fais pour les corriger.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.