Django 2.2 : Vues basées sur les classes et vues basées sur les fonctions

Jean Luc Kabulu
Espace Du Code
Published in
6 min readApr 4, 2019

On me demande souvent pourquoi je n’utilise pas les vues basées sur les classes plus fréquemment. Alors j’ai pensé à partager mes pensées sur ce sujet.

Avant de lire, gardez cela à l’esprit: les vues basées sur les classes ne remplacent pas les vues basées sur les fonctions.

Introduction

Je ne suis pas un développeur Django de la vieille école qui l’utilisait lorsqu’il n’y avait que des vues fonctionnelles et observait la publication des vues basées sur les classes. Mais il fut un temps où seules les vues basées sur les fonctions existaient.

Je suppose qu’il n’a pas fallu longtemps avant que toutes sortes de solutions et de hacks soient créées pour étendre et réutiliser les vues, les rendre plus génériques.

Il fut un temps où les vues génériques basées sur les fonctions étaient une chose. Ils ont été créés pour traiter les cas d’utilisation courants. Mais le problème était qu’ils étaient assez simples et qu’il était très difficile de les étendre ou de les personnaliser (autre que l’utilisation de paramètres de configuration).

Pour résoudre ces problèmes, les vues basées sur les classes ont été créées.

Maintenant, les vues sont toujours des fonctions. Même les vues basées sur les classes.

Lorsque nous les ajoutons à l’URL conf à l’aide de la View.as_view()méthode class, une fonction est renvoyée.

Voici à quoi as_viewressemble la méthode:

class View:     
@classonlymethod
def as_view(cls, **initkwargs):
"""Point d'entrer pour la requete"""
for key in initkwargs:
# Code effacé pour la clarte
# ...

def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):

self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
# code efface pour la clarte
# ...
return view

Certaines parties du code ont été omises pour plus de clarté.

Donc, si vous voulez appeler explicitement une vue basée sur les classes, voici ce que vous devez faire:

return MyView.as_view()(request)

Pour que cela paraisse plus naturel, vous pouvez l’affecter à une variable:

view_function = MyView.as_view() 
return view_function(request)

La fonction de vue renvoyée par la as_view()méthode est la partie externe de chaque vue basée sur les classes. Après l'appel, la vue transmet la demande à la dispatch()méthode, qui exécutera la méthode appropriée en fonction du type de demande ( GET , POST , PUT , etc.).

Exemple de vue basée sur la classe

Par exemple, si vous avez créé une vue étendant la django.views.Viewclasse de base, la dispatch()méthode gérera la logique de la méthode HTTP. Si la demande est un POST , il exécutera la post()méthode dans la vue. Si la demande est un GET , il exécutera la get()méthode dans la vue.

views.py

from django.views import View  class ContactView(View):     
def get(self, request):
# block de code pour la requete GET
def post(self, request):
# block de code pour la requete GET

urls.py

urlpatterns = [     
url(r'contact/$', views.ContactView.as_view(), name='contact'), ]

Exemple de vue basée sur les fonctions

Dans les vues fonctionnelles, cette logique est gérée avec les instructions if:

views.py

def contact(request):     
if request.method == 'POST':
# bloc de code pour la requete POST
else:
# Bloc de code pour la requete GET (PUT, HEAD, DELETE, etc)

urls.py

urlpatterns = [     
url(r'contact/$', views.contact, name='contact'),
]

Ce sont les principales différences entre les vues basées sur les fonctions et les vues basées sur les classes. Maintenant, les vues génériques basées sur les classes de Django sont une autre histoire.

Vues génériques basées sur les classes

Les vues génériques basées sur les classes ont été introduites pour traiter les cas d’utilisation courants dans une application Web, telles que la création de nouveaux objets, la gestion de formulaires, les vues de liste, la pagination, les vues d’archives, etc.

Ils viennent dans le noyau Django, et vous pouvez les implémenter à partir du module django.views.generic.

Ils sont excellents et peuvent accélérer le processus de développement.

Voici un aperçu des vues disponibles:

Vues génériques simples

  • Vue
  • TemplateView
  • RedirectView

Vues détaillées

  • DetailView

Lister les vues

  • ListView

Modification de vues

  • FormView
  • CreateView
  • UpdateView
  • DeleteView

Vues basées sur la date

  • ArchiveIndexView
  • YearArchiveView
  • MonthArchiveView
  • WeekArchiveView
  • DayArchiveView
  • TodayArchiveView
  • DateDetailView

Vous pouvez trouver plus de détails sur chaque implémentation dans la documentation officielle: API intégrée aux vues basées sur les classes .

Je trouve cela un peu déroutant, car les implémentations génériques utilisent beaucoup de mixins, donc au moins pour moi, le flux de code n’est parfois pas très évident.

Voici maintenant une excellente ressource, également issue de la documentation Django, un index aplati contenant tous les attributs et méthodes de chaque vue: Vues génériques basées sur des classes — index aplati . Je garde celui-ci dans mes favoris.

Les différentes écoles de vues Django

Ecole de “Utiliser toutes les vues génériques”!
Cette école de pensée est basée sur l’idée que, puisque Django fournit une fonctionnalité permettant de réduire votre charge de travail, pourquoi ne pas utiliser cette fonctionnalité? Nous avons tendance à appartenir à cette école de pensée et nous en avons fait un grand succès en construisant rapidement puis en maintenant un certain nombre de projets.

Ecole de “Il suffit d’utiliser django.views.generic.View”
Cette école de pensée est basée sur l’idée que la base Django CBV en fait juste assez et qu’elle est “le True CBV, tout le reste est un CBV générique”. Au cours de la dernière année, nous avons constaté que cette approche pouvait s’avérer très utile pour les tâches complexes pour lesquelles l’approche basée sur les ressources consistant à «Utiliser toutes les vues» échoue. Nous couvrirons quelques cas d’utilisation pour cela dans ce chapitre.

École de « Évitez les à moins que vous êtes en train de vues sous — classement »
dit Jacob Kaplan-Moss, « Mon conseil général est de commencer avec vue sur la fonction , car ils sont plus faciles à lire et à comprendre, et utiliser uniquement CBV où vous en avez besoin. Où avez-vous besoin d’eux? N’importe quel endroit où vous avez besoin d’une bonne quantité de code pour pouvoir être réutilisé entre plusieurs vues. ”

Les auteurs disent dans le livre qu’ils sont à la première école. Personnellement, je suis à la troisième école. Mais comme ils l’ont dit, il n’y a pas de consensus sur les meilleures pratiques.

Avantages et inconvénients

À titre de référence, certains avantages et inconvénients des vues basées sur les fonctions et des vues basées sur les classes.

  1. Avantages Les inconvénients Vues basées sur les fonctions

Avantages

  • Simple à mettre en œuvre
  • Facile à lire
  • Flux de code explicite
  • Utilisation directe des décorateurs

Inconvenients

  • Difficile d’étendre et de réutiliser le code
  • Gestion des méthodes HTTP via la création de branches conditionnelles

Vues basées sur les classes

  1. Avantages
  • Peut être facilement étendu, réutiliser le code
  • Peut utiliser des techniques OO telles que mixins (héritage multiple)
  • Traitement des méthodes HTTP par des méthodes de classe séparées
  • Vues génériques intégrées basées sur les classes

2. Inconvenients

  • Plus difficile à lire
  • Flux de code implicite
  • Code caché dans les classes parentes, mixins
  • L’utilisation de décorateurs de vue nécessite une importation supplémentaire ou un remplacement de méthode

Il n’y a pas de vrai ou de faux. Tout dépend du contexte et des besoins. Comme je l’ai mentionné au début de cet article, les vues basées sur les classes ne remplacent pas les vues basées sur les fonctions. Il y a des cas où les vues basées sur les fonctions sont meilleures. Dans d’autres cas, les vues basées sur les classes sont meilleures.

Par exemple, si vous implémentez une vue liste et que vous pouvez le faire fonctionner simplement en sous- ListViewclassant les attributs et en les redéfinissant. Génial. Fonce.

Désormais, si vous effectuez une opération plus complexe, gérant plusieurs formulaires à la fois, une vue basée sur les fonctions vous sera plus utile.

Conclusions

La raison pour laquelle j’utilise souvent des vues fonctionnelles dans mes exemples d’articles, c’est parce qu’elles sont beaucoup plus faciles à lire. Beaucoup de lecteurs qui tombent sur mon blog sont des débutants. Les vues basées sur les fonctions communiquent mieux, car le flux de code est explicite.

D’habitude, je commence toujours mes vues en tant que vues fonctionnelles. Si je peux utiliser une vue générique basée sur les classes simplement en surchargeant les attributs, j’y vais. Si j’ai des besoins très spécifiques et que la réplication s’effectue sur plusieurs vues, je crée ma propre vue générique personnalisée django.views.generic.View.

Maintenant, un conseil général tiré de la documentation de Django: Si vous rencontrez des difficultés pour implémenter votre vue en tant que sous-classe d’une vue générique, il peut être plus efficace d’écrire uniquement le code dont vous avez besoin, en utilisant votre propre classe ou vues fonctionnelles.

--

--

Jean Luc Kabulu
Espace Du Code

Developer Student Club Lead |Flutter Lubumbashi lead|Github Campus Expert | FullStack Devs, And Proudly