Entwickeln Sie Ihre Django-Apps, während Ihr Unternehmen wächst

Blogvorlage 36

Djangoapp2
Wenn wir mit Django mit dem Prototyping unserer ersten Webanwendung beginnen, neigen wir dazu, eine Django-App zu erstellen und alle Modelle darin zu integrieren. Der Grund ist einfach: Es gibt nicht viele Modelle und die Geschäftslogik ist simpel. Mit dem Wachstum des Unternehmens kommen jedoch weitere Modelle und Geschäftslogik hinzu – und irgendwann kann unsere Anwendung in eine missliche Lage geraten: Es wird immer schwieriger, Fehler zu finden, und das Hinzufügen neuer Funktionen dauert immer länger, selbst wenn sie einfach sind. In diesem Blogbeitrag erläutern wir, wie wir verschiedene Django-Apps nutzen, um Modelle und Geschäftslogik so zu reorganisieren, dass sie mit dem Wachstum unseres Unternehmens mitwachsen. Wir veranschaulichen den Ablauf der Änderung anhand einer einfachen Fallstudie.

Prototyping-Phase – eine einfache Fallstudie

Wir beginnen mit einer einfachen Anwendung namens „Weblog“, die es den Benutzern ermöglicht, Blogs zu erstellen und zu veröffentlichen. Wir erstellen eine App namens Weblog. Und die Modelle sind wie folgt.
In weblog/models.py:

Klasse Autor (Modelle.Modell): Benutzer = Modelle.OneToOneField('Authentifizierung.Benutzer') ... Klasse Blog (Modelle.Modell): Autor = Modelle.ForeignKey(Autor) Kategorie = Modelle.CharField(Auswahl=((TECH, 'Technik'), (SPORT, 'Sport'), (MODE, 'Mode')), max. Länge=10) Inhalt = Modelle.TextField(max. Länge=10240, leer=Wahr) wird_veröffentlicht = Modelle.BooleanField(Standard=Falsch) ...

Nehmen wir nun an, dass der Rest der Anwendung basierend auf den oben genannten Modellen fertiggestellt ist. Die Benutzer können sich jetzt anmelden und ihre Blogs mit unserer Anwendung erstellen und veröffentlichen.
Sich weiterentwickelnder Ansatz I – Fügen Sie derselben App immer wieder neue Geschäftslogik hinzu
Angenommen, wir haben einen neuen Bedarf. Um mehr Autoren für die Erstellung von Inhalten mit unserer Anwendung zu gewinnen, zahlen wir die Autoren auf Basis der Aufrufzahlen. Der Preis beträgt 10 US-Dollar pro 1000 Aufrufe. Die Auszahlung erfolgt einmal im Monat.
Da die neue Anforderung recht einfach klingt, reicht ein regulärer Ansatz, bei dem die neuen Modelle und die Logik in die bestehende App integriert werden, aus. Zunächst fügen wir der „Weblog“-App ein neues Modell hinzu, wie unten dargestellt:
In weblog/models.py:

... Klasse MonthlyViewCount(Modelle.Modell): Blog = Modelle.ForeignKey(Blog) Monat = Modelle.DateField() Anzahl = Modelle.PositiveIntegerField(Standard=1) ...

Für jeden neuen Aufruf eines Blogs erhöhen wir die Anzahl auf Monatsbasis oder erstellen einen neuen Monatliche Aufrufanzahl protokollieren, ob dies die erste Ansicht in diesem Monat ist. Der Code sieht folgendermaßen aus:

Klasse Blog (Modelle.Modell): ... def increase_view_count (selbst): jetzt = Zeitzone.jetzt() Monat = Datum/Uhrzeit (Jahr=jetzt.Jahr, Monat=jetzt.Monat, Tag=1) view_count, erstellt = \ MonthlyViewCount.objects.get_or_create (Blog=selbst, Monat=Monat), falls nicht erstellt: view_count.count += 1 view_count.save ()

Am Ende jedes Monats führen wir einen Cron-Task aus, der alle Aufrufzahlen für jeden Autor zusammenfasst und die entsprechende Zahlung an ihn sendet. Hier ist der Pseudocode:
In weblog/tasks.py:

@periodic_task(run_every=crontab(Tag des Monats=1, Stunde=0, Minute=1)) def send_viewcount_payment_to_authors(): für Autor in Authors.objects.authors_with_viewscounts(Monat=vorheriger_Monat): Gesamtansichtsanzahl = Autor.get_total_view_count_for_month(Monat=vorheriger_Monat) Zahlungsbetrag = (Gesamtansichtsanzahl / 1000) * 10.00 Autor.send_payment(Zahlungsbetrag)

Der oben beschriebene Ansatz scheint für die Bearbeitung einer einfachen Änderungsanforderung wie dieser geeignet zu sein. Es werden jedoch immer neue Anforderungen eingehen.
Sich weiterentwickelnder Ansatz II – Organisieren Sie die Geschäftslogik in verschiedenen Django-Apps
Nun gibt es eine neue Anforderung. Um die Autoren zu ermutigen, Inhalte in bestimmten Kategorien zu erstellen, möchte das Business-Team die Preisstrategie kategoriebasiert anpassen. Jede Kategorie erhält einen anderen Preis. Die Preistabelle sieht beispielsweise wie folgt aus:

 Preis (pro 1000 Aufrufe)
Technologie$15
Sport$10
Fashion$5

Diese neue Anforderung scheint so einfach zu sein, dass wir einfach ein neues Modell in der bestehenden App erstellen können, um den Kategorie-Basispreis zu speichern und die Cron-Task zu aktualisieren, um bei der Gesamtsumme nach dem kategoriebasierten Preis zu suchen. Die gesamte Änderung dauert weniger als 30 Minuten und alles ist einsatzbereit.
Es gibt jedoch zwei große Probleme, wenn immer mehr neue Modelle und Geschäftslogiken in die Haupt-Weblog-App integriert werden.

  1. Die Hauptanwendung übernimmt die Verantwortung für die Geschäftslogik verschiedener Domänenkenntnisse. Die Klassendateien werden größer und sind nicht mehr zu warten.
  2. Die Agilität wird beeinträchtigt, da es schwieriger ist, ein Problem zu debuggen und das Hinzufügen neuer Funktionen langsamer ist.

In Django können wir verschiedene Apps verwenden, um die Geschäftslogik verschiedener Domänen zu organisieren, und Signale, um die Kommunikation zwischen Apps zu verwalten. In unserem Beispiel versuchen wir, alle abrechnungsbezogenen Modelle und Methoden in die neue App „Billing“ zu verschieben.
Zunächst verschieben wir alle abrechnungsbezogenen Modelle in die neue Abrechnungs-App.
In Abrechnung/Modelle.py:

... Klasse MonthlyViewCount(models.Model): Blog = models.ForeignKey('weblog.Blog', related_name='+') Monat = models.DateField() Anzahl = models.PositiveIntegerField(Standard=1) ... Klasse CategoryBasedPrice(models.Model): Kategorie = models.CharField(Auswahl=((TECH, 'Tech'), (SPORT, 'Sport'), (FASHION, 'Fashion')), Preis = models.MoneyField(...) ...

Bei jedem neuen Aufruf eines Blogartikels muss die Abrechnungs-App informiert werden, damit sie diesen entsprechend erfassen kann. Dazu definieren wir ein Signal in der „Weblog“-App und erstellen einen eigenen Handler in der „Abrechnungs“-App, der das empfangene Signal verarbeitet.
Wir bewegen die Blog.increase_view_count()in Abrechnung/Empfänger.py als Signalhandler:

def increase_view_count(sender, blog, **kwargs): jetzt = timezone.now() Monat = datetime(Jahr=now.year, Monat=now.month, Tag=1) view_count, erstellt = \ MonthlyViewCount.objects.get_or_create( Blog=Blog, Monat=Monat ) falls nicht erstellt: view_count.count += 1 view_count.save()

Dann wird ein neues Signal erzeugt in weblog/signals.py:

von django.dispatch importiere Signal von Abrechnungsimportempfängern ... blog_viewed = Signal(providing_args=['blog']) blog_viewed.connect(receivers.increase_view_count)

Und wir müssen auch einen Signal-Sende-Snippet in eine der Ansichtsmethoden einfügen in weblog/views.py:

von weblog.signals importiere blog_viewed ... def view_blog(request, blog_id): versuche: blog = Blog.objects.get(blog_id) außer ValueError: raise Http404() blog_viewed.send(Blog, blog=blog) response.write(blog.render_content()) returniere Antwort

Schließlich können wir die abrechnungsbezogene Cron-Aufgabe verschieben send_viewcount_payment_to_authors ab weblog/tasks.py zu Abrechnung/Aufgaben.py und fügen Sie eine neue Logik hinzu, um die neue kategoriebasierte Preisgestaltung zu handhaben.
Obwohl der obige Ansatz im Vergleich zum regulären Ansatz, bei dem einfach alles Neue in die Haupt-App eingefügt wird, mehr Codeänderungen und Refactoring erfordert, hat er doch mehrere Vorteile, die ihn lohnenswert machen.

  1. Die Geschäftslogik einer bestimmten Domäne wird von den anderen Domänen getrennt, wodurch die Codebasis leichter zu warten ist.
  2. Tritt während der Laufzeit ein Problem auf, kann die Ursache anhand des Symptoms zeitnah im Anwendungsbereich lokalisiert werden. Dies verkürzt die Debugging-Zeit.
  3. Wenn ein neuer Entwickler an Bord kommt, kann er zunächst mit der Arbeit an einer einzelnen App beginnen, was die Lernkurve abmildert.
  4. Wenn wir uns dazu entschließen, die gesamte Geschäftslogik in einer bestimmten Domäne zu verwerfen (z. B. weil alle Abrechnungsfunktionen nicht mehr benötigt werden), können wir diese App einfach entfernen und alles andere sollte weiterhin normal ausgeführt werden.

Fazit
Viele Startups nutzen Django, um Prototypen ihrer Produkte oder Dienstleistungen zu entwickeln. Darüber hinaus kann Django das Wachstum ihres Unternehmens gut bewältigen. Ein wichtiger Aspekt ist es, die Geschäftslogik von Zeit zu Zeit zu überdenken und in verschiedene Apps zu überführen und die Verantwortung für jede App so einfach wie möglich zu halten.