Faites évoluer vos applications Django à mesure que votre entreprise se développe

Modèle de blog 36

Djangoapp2
Lorsque nous commençons à prototyper notre première application Web avec Django, nous avons toujours tendance à créer une application Django et à mettre tous les modèles dans cette application. La raison est simple : il n’existe pas beaucoup de modèles et la logique métier est simple. Mais avec la croissance de l'entreprise, de plus en plus de modèles et de logiques métier sont ajoutés. Un jour, nous pourrions trouver notre application dans une position délicate : il est de plus en plus difficile de localiser un bug et il faut de plus en plus de temps pour ajouter de nouvelles fonctionnalités, même si elles le sont. simple. Dans ce blog, nous expliquerons comment utiliser différentes applications Django pour réorganiser les modèles et la logique métier afin qu'ils évoluent avec la croissance de notre entreprise. Nous illustrerons également le flux du changement avec une étude de cas simple.

Étape de prototypage – une étude de cas simple

Nous partons d'une simple application appelée « Weblog » qui permet aux utilisateurs de créer et de publier des blogs. Nous créons une application appelée blog. Et les modèles sont les suivants.
In blog/models.py:

classe Auteur (models.Model): utilisateur = models.OneToOneField ('authentication.User') ... classe Blog (models.Model): auteur = models.ForeignKey (Auteur) catégorie = models.CharField ( choix = ((TECH , 'Tech'), (SPORT, 'Sport'), (FASHION, 'Fashion')), max_length=10 ) content = models.TextField( max_length=10240, blank=True ) is_published = models.BooleanField(default=False )...

Supposons maintenant que le reste de l’application soit complété sur la base des modèles ci-dessus. Les utilisateurs peuvent désormais se connecter, créer et publier leurs blogs à l'aide de notre application.
Approche évolutive I – continuez à ajouter de nouvelles logiques métier dans la même application
Disons que nous avons une nouvelle exigence. Afin d'inciter davantage d'auteurs à créer du contenu à l'aide de notre application, nous paierons les auteurs en fonction du nombre de vues. Le prix est de 10 $ pour 1000 XNUMX vues. Et le paiement est envoyé une fois par mois.
Étant donné que la nouvelle exigence semble assez simple, une approche régulière qui intègre les nouveaux modèles et la nouvelle logique dans l'application existante est suffisante. Tout d’abord, nous ajoutons un nouveau modèle dans l’application « weblog » comme ci-dessous :
In blog/models.py:

... classe MonthlyViewCount(models.Model): blog = models.ForeignKey(Blog) mois = models.DateField() count = models.PositiveIntegerField(default=1) ...

Pour chaque nouvelle vue d'un blog, nous augmentons le décompte en fonction du mois ou créons une nouvelle Nombre de vues mensuel enregistrez s'il s'agit de la première vue de ce mois. Le code ressemble à :

class Blog(models.Model): ... def Increase_view_count(self): now = timezone.now() mois = datetime(year=now.year,month=now.month, day=1) view_count, créé = \ MonthlyViewCount .objects.get_or_create( blog=self,month=month ) s'il n'est pas créé : view_count.count += 1 view_count.save()

À la fin de chaque mois, nous exécutons une tâche cron qui regroupe tous les nombres de vues pour chaque auteur et leur envoie le paiement en conséquence. Voici le pseudo code :
In blog/tâches.py:

@periodic_task(run_every=crontab(day_of_month=1, hour=0, minute=1)) def send_viewcount_payment_to_authors() : pour l'auteur dans Authors.objects.authors_with_viewscounts(month=previous_month) : total_view_count = author.get_total_view_count_for_month(month=previous_month) payment_amount = (total_view_count / 1000) * 10.00 author.send_payment(payment_amount)

L'approche ci-dessus semble convenir pour gérer une simple demande de modification comme celle-ci. Mais il y aura toujours de nouvelles exigences.
Approche évolutive II – organiser la logique métier dans différentes applications Django
Nous avons maintenant une nouvelle exigence. Pour encourager les auteurs à créer du contenu dans certaines catégories, l'équipe commerciale souhaite ajuster la stratégie de récompense en une stratégie basée sur les catégories. Chaque catégorie aura un prix de récompense différent. Supposons que le tableau des prix ressemble à ce qui suit :

 Prix ​​(pour 1000 vues)
Technologie$15
Sports $10
Mode$5

Cette nouvelle exigence semble également suffisamment simple pour que nous puissions simplement créer un nouveau modèle dans l'application existante pour stocker le prix de base de la catégorie et mettre à jour la tâche périodique pour rechercher le prix basé sur la catégorie lors de l'agrégation du total. L’ensemble du changement prendra moins de 30 minutes et tout est prêt.
Mais il existe deux problèmes majeurs liés à l'intégration de plus en plus de nouveaux modèles et de nouvelles logiques métier dans l'application principale « weblog ».

  1. L'application principale devient responsable de la logique métier des différentes connaissances du domaine. Les fichiers de classe deviennent plus gros et impossibles à maintenir.
  2. L'agilité est compromise car il est plus difficile de déboguer un problème et l'ajout de nouvelles fonctionnalités est plus lent.

Dans Django, nous pouvons utiliser différentes applications pour organiser la logique métier de différents domaines et signaux pour gérer la communication entre les applications. Dans notre exemple, nous allons essayer de déplacer tous les modèles et méthodes liés à la facturation dans la nouvelle application appelée « facturation ».
Tout d’abord, nous déplaçons tous les modèles liés à la facturation vers la nouvelle application de facturation.
In facturation/models.py:

... classe MonthlyViewCount(models.Model): blog = models.ForeignKey('weblog.Blog', Related_name='+') mois = models.DateField() count = models.PositiveIntegerField(default=1) ... classe CategoryBasedPrice(models.Model): catégorie = models.CharField( choix=((TECH, 'Tech'), (SPORT, 'Sport'), (FASHION, 'Fashion')), prix = models.MoneyField(... )...

Désormais, pour chaque nouvelle vue d'un article de blog, l'application de facturation doit être informée afin qu'elle puisse les enregistrer en conséquence. Pour ce faire, nous pouvons définir un signal dans l'application « weblog » et créer un seul gestionnaire dans l'application « facturation » pour traiter le signal reçu.
Nous déplaçons le Blog.increase_view_count()développement facturation/récepteurs.py en tant que gestionnaire de signaux :

def raise_view_count(sender, blog, **kwargs) : now = timezone.now() mois = datetime(year=now.year,month=now.month, day=1) view_count, créé = \ MonthlyViewCount.objects.get_or_create( blog=blog,month=month ) s'il n'est pas créé : view_count.count += 1 view_count.save()

Ensuite, un nouveau signal est créé dans blog/signaux.py:

depuis django.dispatch import Signal des récepteurs d'importation de facturation... blog_viewed = Signal(providing_args=['blog']) blog_viewed.connect(receivers.increase_view_count)

Et nous devons également injecter un extrait d'envoi de signal dans l'une des méthodes d'affichage de blog/views.py:

à partir de weblog.signals import blog_viewed ... def view_blog(request, blog_id) : essayez : blog = Blog.objects.get(blog_id) sauf ValueError : raise Http404() blog_viewed.send(Blog, blog=blog) réponse.write( blog.render_content()) renvoie la réponse

Enfin, nous pouvons déplacer la tâche périodique liée à la facturation send_viewcount_payment_to_authors à partir de blog/tâches.py à facturation/tâches.py et ajoutez une nouvelle logique pour gérer la nouvelle tarification basée sur la catégorie.
Bien que comparée à l'approche habituelle, qui met simplement tout ce qui est nouveau dans l'application principale, l'approche ci-dessus nécessite davantage de modifications de code et de refactorisation, mais elle présente plusieurs avantages qui en valent la peine.

  1. La logique métier d'un domaine spécifique est séparée des autres domaines, ce qui facilite la maintenance de la base de code.
  2. Si un problème survient pendant l'exécution, la cause peut être rapidement localisée dans la portée d'une application en fonction du symptôme. Cela réduit le temps de débogage.
  3. Lorsqu'un nouveau développeur est intégré, il peut d'abord commencer à travailler sur une seule application, ce qui modérera la courbe d'apprentissage.
  4. Si nous décidons de rendre obsolète l'ensemble de la logique métier dans un domaine spécifique (par exemple, toutes les fonctionnalités de facturation ne sont plus nécessaires), nous pouvons simplement supprimer cette application et tout le reste devrait continuer à fonctionner normalement.

Conclusion
De nombreuses startups utilisent Django pour prototyper leur produit ou service. De plus, Django peut assez bien gérer la croissance de son entreprise. Un aspect important est de repenser et de réorganiser la logique métier dans différentes applications de temps en temps et de garder la responsabilité de chaque application aussi simple que possible.