Des années plus tard, je n’aime toujours pas les CBV


Les Class Based Views se trouvent maintenant partout en Django. Je les comprends aujourd’hui très bien, et les utilise souvent au mieux. Dernièrement j’ai dû utiliser django-rest-framework, une très belle application, qui fait un usage utile et massif des CBV, et effectivement, cette architecture m’a rendu très productif.

Mais je maintiens ce que je dis depuis le début : ce n’est pas un pas en avant.

D’abord, qui dit CBV dit référence constante à la documentation. J’ai été productif avec CBV parce que :

  • Je connais l’API Django sur le bout des doigts.
  • Je comprends parfaitement les CBV (et la POO en Python en général).
  • Je lis très vite, et j’ai l’habitude de fouiller dans les docs.
  • Je me balade dans le code source naturellement.

Mais ce n’est pas comme ça que c’est censé être. Si vous utilisez une belle API, comme requests ou path.py, vous n’avez PAS besoin de tout cela. Vous jetez un coup d’œil à la doc, et vous faites 80% du boulot dans le shell, puis de temps à autre, vous vous référez à la documentation sur les points ambiguës. Je n’ai jamais du aller dans le code source de requests, je n’ai jamais eu besoin de comprendre urllib de fond en comble pour utiliser requests, et je n’ai pas besoin de connaître les subtilités de plusieurs paradigmes de programmation pour utiliser requests.

Alors oui, requests ne peut en aucun cas être comparé à Django en terme de taille et de couverture de besoin, et certes, en tant que professionnel averti, je suis tenu d’être capable de faire tout cela. Mais il y a quand même une énorme différence d’effort à fournir, et de qualification à avoir, pour l’usage de cette techno.

En prime, il est TRÈS difficile de débugger une CBV :

  • Dans une vue générique sous forme de fonction, on peut juste faire import ipdb, et faire un step puis débugger tranquillement. Dans une CBV, vous le mettez où le break point ? Soit vous overridez une méthode (et il faut savoir par cœur laquelle), soit vous faites un wrapper provisoir sous forme de fonction (!), soit vous mettez le break cash dans le code source de la lib. C’est nul à chier, et improductif. Et certainement pas à la portée d’un débutant.
  • Les mixins ont un tas de comportements implicites, qu’il faut connaître pour comprendre pourquoi ceci fait cela. Et comme il y a généralement 3 ou 4 mixins (d’ailleurs, combien de dev peuvent donner la définition d’un mixin ?), et bien si il y a un problème, il y a 4 sources possibles. Qui héritent parfois d’autres classes, ce qui démultiplie le truc.
  • Quand ça plante le stack trace est blindée de références à droite et à gauche. Un putain de labyrinthe.

Rajoutez à cela que la syntaxe est verbeuse comme c’est pas permis :

def get_context_data(self, *args, **kwargs):
    context = super(MaClass, self).get_context_data(*args, **kwargs)
    context['ma_var'] = "ma valeur"
    return context

Pour rajouter UNE variable dans le contexte ? Rhaaaaaaaaaaa. Je code en Python, pas en Java !

Et terminez sur le fait que pour utiliser tous les décorateurs codés depuis 5 ans, vous avez une syntaxe bien pourrie ou alors des réimplementations complètes sous forme de mixins. Yeah !

Vous comprendrez que ça me gonfle.

Tout ça pour quel gain ? Oui on gagne un peu en flexibilité, mais ça ne compense pas tout le reste, et ça ne permet en rien de faire des choses qu’on ne pouvait pas faire avant.

Je n’ai pas vu encore la moindre utilisation des CBV qui me fasse dire, “putain c’est tellement mieux qu’avant pour cette partie”. Ni aucune lib qui me fasse dire : “ouais, on aurait pas pu le faire aussi bien avec des vues sous forme de fonctions”.

Avec les CBV devenant la manière par défaut de coder les vues en Django, le framework devient beaucoup moins accessible au débutant, alors que sa facilité d’usage était un de ses points forts.

Bref, je suis de l’avis de Nick Coghlan, les CBV ne sont pas une erreur, elles ont leur utilité, mais balancer à la poubelle les vues sous forme de fonction est une vaste connerie.

24 thoughts on “Des années plus tard, je n’aime toujours pas les CBV

  • dodoecchi

    (résumé)Le Class Bbased Views -> Les… Based Views
    (titre)Des années plus tards -> tard
    J’ai été productif avec CVB parce que : -> CBV
    Je n’ai jamais du allé -> aller

  • Flo

    “la définition d’un mixin” : c’est une classe abstraite si j’ai bien compris ?

  • Sam Post author

    Oui, c’est une classe abstraite, mais qui généralement n’a qu’une seule particularité / fonctionalité. Elle doit rester très simple, car le but et de l’utiliser avec plein d’autres mixins (de les “mixer”) qui font chacun un truc simple, pour obtenir une classe fille avec un comportement complexe.

  • foxmask

    ca donnerait presque envie de lâcher django … mais pour quoi ?

  • Sam Post author

    Vive les trolls !

    Pour remplacer django il faut une solution qui possède ses facilités pour les formulaires, l’admin autogénérée, les flux rss, la pagination… Et je ne compte pas tout l’écosystème d’apps autour de Django.

    Flask est un très bon produit, mais c’est un complément à Django, pas un concurrent, et donc pas un remplaçant.

  • G-rom

    Tout à fait d’accord, mais comme tu parlais de faire du REST je pensais que tu n’avais besoin que de ça. Je fais du back-end restful avec juste Flask / PyMongo et une stack dédiée pour la gestion des utilisateurs, et ça le fait.

  • Sam Post author

    Pareil pour REST. Django rest framework permet de faire des choses automatisées de partout : vérification des permissions, sérialisation, standardisation des messages d’erreurs, récupération des données en format multiple.

    Dès qu’on commence à taper dans un gros projet, Django a des atouts fantastiques.

  • foxmask

    Ce qui est con c’est que vous ne devez pas être que 3 à l’avoir en travers (la suppression des FBV s’entend) et pourtant rien de bouge pour les remettre ou pas de potentiel fork pour conserver ce qui était si souple. Peut être que la majorité des dev le prenne comme une amélioration ( majeure ) et s’en contente.
    En tout cas c’est effectivement bien dommage.

  • Sam Post author

    Honêtement je pense que si la prochaine version les vire, je vais faire une app qui les réintègre. Ou alors je les ajoutes directement dans django-quicky. Faut pas déconner.

  • foxmask

    hehe :) ya pas un gros impact sur les perfs de passer par des CBV à présent ? j’enfonce surement une porte ouverte.

  • G-rom

    Baah vérif des perm. quand t’as une stack AAA ta vérif tu la fait dans le code métier, je ne laisse pas le FW le faire (faible couplage toussa toussa). La sérialisation, quand tu ne fais que du JSON, t’as pas besoin de serialiseur, json dumps loads et roule jean raoul, standardisation des messages d’erreurs = exception standardisée tout simplement, et format multiple… pas besoin pour l’instant.

    Bref, même sur des gros projets, tout dépend du besoin bien sûr, je préfère la souplesse de Flask. Après quand tu as capitalisé dessus depuis un moment et que tu as déjà tes propres validators pour tes model, ta propre surcouche au JSON codec, (bin ouais les datetime ne sont pas convertis automatiquement), ta propre stack Auth, etc, c’est sûr que c’est plus simple aussi.

    Mais j’ai regardé django rest framework vite fais, franchement je trouve qu’il y a beaucoup de verbatim autour des data (model + serializer) et que la façon de faire les view + route n’est pas hyper souple. Si c’est pour galérer dès qu’il faut toucher aux headers ou autre subtilités, non merci.

    • Sam Post author

      Le vérif des perms est au contraire quelque chose que le framework peut énormément faciliter, à la fois en fournissant des hooks bien pensés, et à la fois en proposant des vérifications génériques de base.

      De surcroît, la sérialisation (qui n’est pas que du JSON, mais admettons que le XML n’interesse pas), ne se fait pas qu’à la sortie. Il se fait aussi en entrée. Hors, forcer ton client à envoyer du json plutôt qu’un query string ou du form encoded, c’est limiter tes clients qui peuvent être écrits dans des tas de langages dans lesquels l’un est plus facile que l’autre. Le framework autorise tout ça de manière transparente, et gratuitement.

      Par ailleurs, DRF permet facilement la sérialisation des modèles de l’ORM, c’est autant de travail en moins, mais également de la pagination. C’est un vrai plus. Les sérialiseurs servent également à encapsuler la validation de données, qui permet de réutiliser cette logique à bien des endroits.

      Il est vrai que c’est plus lourd et verbeux que flask (la concision et la légèreté est le point fort de ce micro framework), mais ce que tu en obtiens n’est pas comparable. De plus, avec le principes des viewsets, DRF permet d’écrire des vues REST CRUD complètes sur une ressource en base de données de manière très très propre (le GET, le POST, le PUT et le DELETE sont respectés) en quelques lignes, avec une documentation autogénérée, dynamique et navigable via le browser. Ce genre de choses est une vraie merveille.

  • JEEK

    Bon pour moi…
    …CBV, ça ne m’évoque que les “coups et blessures volontaires” !

    huhu’

    Si vous me cherchez, j’suis déjà dehors… ->[]
    ;-)

  • G-rom

    Je vois ce que tu veux dire Sam. C’est une autre façon de penser et d’architecturer son projet, en partant de zéro un jour j’y laisserai sûrement une chance. Par contre avec l’archi actuelle et les lib maison dont je dispose je vais plus vite et plus proprement.

  • Sam Post author

    Le dev flask pour les projets de taille humain est très rapide, c’est la force de ce produit. C’est une très bonne chose qu’il existe et qu’il ait une bonne communauté. Il y a de la place pour toutes ces technos, c’est ça qui est chouette.

  • G-rom

    Si ça pouvait aider à ne pas se faire bouffer par Ruby (rails) :D

  • Sam Post author

    Ruby n’existe presque pas en dehors Rails et quelques produits Web, je suis plus concerné par nodejs vu l’essort de javascript ces temps-ci.

  • G-rom

    Pour faire beaucoup de JS côté front, (backbonejs / marionette) j’ai une légère préférence pour celui-ci que pour rails. Pour du proto de backend REST j’ai même regardé un peu expressojs. Oui je fais des infidélités à Python ? Et alors ? :p

  • Mikoko

    Bien je peux confirmer que pour un débutant les CBV c’est pas facile… Pour moi tout à commencé à s’éclaircir en allant voir leur code source. La lecture de la doc m’a juste donner la migraine en effet pour quelqu’un qui connait l’API cela doit plus facile

  • Sam Post author

    Ca n’a pas changé. DRF en fait bonne usage, mais le succès de flask prouve que la simplicité a encore beaucoup de succès. Et le debuggage ne s’est pas amélioré.

Comments are closed.

Des questions Python sans rapport avec l'article ? Posez-les sur IndexError.