Django: "Projekte" gegen "Apps"

202

Ich habe ein ziemlich komplexes "Produkt", das ich mit Django bauen möchte. Ich werde es vermeiden, die Begriffe "Projekt" und "Anwendung" in diesem Zusammenhang zu verwenden, da mir ihre spezifische Bedeutung in Django nicht klar ist.

Projekte können viele Apps haben. Apps können von vielen Projekten gemeinsam genutzt werden. Fein.

Ich erfinde das Blog oder Forum nicht neu - ich sehe keinen Teil meines Produkts in irgendeinem Kontext wiederverwendbar. Intuitiv würde ich diese eine "Anwendung" nennen. Mache ich dann meine ganze Arbeit in einem einzigen "App" -Ordner?

Wenn ja ... in Bezug auf Djangos project.appNamespace ist meine Neigung zu verwenden myproduct.myproduct, aber das ist natürlich nicht erlaubt (aber die Anwendung, die ich erstelle, ist mein Projekt und mein Projekt ist eine Anwendung!). Ich glaube daher, dass ich mich vielleicht an Django wenden soll, indem ich eine App pro "signifikantem" Modell erstelle, aber ich weiß nicht, wo ich die Grenzen in meinem Schema ziehen soll, um es in Apps zu unterteilen - ich habe viel von Modellen mit relativ komplexen Beziehungen.

Ich hoffe, es gibt eine gemeinsame Lösung dafür ...

Dolph
quelle
1
Die Dokumente erklären den Unterschied zwischen "Anwendung" und "Projekt" hier: docs.djangoproject.com/de/dev/ref/applications/…
guettli

Antworten:

56

Was soll Sie davon abhalten, etwas zu benutzen myproduct.myproduct? Was Sie dazu ungefähr benötigen, besteht darin, Folgendes zu tun:

django-admin.py startproject myproduct
cd myproduct
mkdir myproduct
touch myproduct/__init__.py
touch myproduct/models.py
touch myproduct/views.py

und so weiter. Würde es helfen, wenn ich sagte, views.pydass nicht angerufen werden muss views.py? Vorausgesetzt, Sie können im Python-Pfad eine Funktion benennen (normalerweise package.package.views.function_name), die behandelt wird. So einfach ist das. All dieses "Projekt" / "App" Zeug ist nur Python-Pakete.

Wie solltest du das machen? Oder besser gesagt, wie könnte ich das machen? Nun, wenn Sie ein erhebliches Stück wiederverwendbarer Funktionalität schaffen, sagen wie ein Markup - Editor, das ist , wenn Sie einen „Top - Level - App“ erstellen , welche enthalten könnte widgets.py, fields.py, context_processors.pyetc - alles Dinge , die Sie importieren wollen könnten.

Wenn Sie so etwas wie ein Blog in einem Format erstellen können, das für alle Installationen recht allgemein ist, können Sie es in einer App mit einer eigenen Vorlage, einem statischen Inhaltsordner usw. zusammenfassen und eine Instanz eines Django-Projekts konfigurieren, um dies zu verwenden Inhalt der App.

Es gibt keine festen Regeln, die besagen, dass Sie dies tun müssen, aber es ist eines der Ziele des Frameworks. Die Tatsache, dass alles, einschließlich Vorlagen, es Ihnen ermöglicht, von einer gemeinsamen Basis aus zu integrieren, bedeutet, dass Ihr Blog genau in jedes andere Setup passen sollte, indem Sie sich einfach um seinen eigenen Teil kümmern.

Um jedoch auf Ihr eigentliches Problem einzugehen, gibt es keinen Hinweis darauf, dass Sie nicht mit dem Projektordner der obersten Ebene arbeiten können. Genau das tun Apps, und Sie können es tun, wenn Sie es wirklich wollen. Ich neige jedoch aus mehreren Gründen dazu:

  • Djangos Standard-Setup macht das nicht.
  • Oft möchte ich eine Haupt-App erstellen, also erstelle ich eine, die normalerweise aufgerufen wird website. Zu einem späteren Zeitpunkt möchte ich jedoch möglicherweise die ursprüngliche Funktionalität nur für diese Site entwickeln. Um es entfernbar zu machen (unabhängig davon, ob ich es jemals tue oder nicht), neige ich dazu, ein separates Verzeichnis zu erstellen. Dies bedeutet auch, dass ich diese Funktionalität löschen kann, indem ich die Verknüpfung dieses Pakets aus der Konfiguration aufhebe und den Ordner entferne, anstatt die richtigen URLs aus einem globalen Ordner urls.py zu löschen.
  • Sehr oft, selbst wenn ich etwas unabhängig machen möchte, braucht es einen Ort zum Leben, während ich mich darum kümmere / es unabhängig mache. Grundsätzlich der obige Fall, aber für Sachen, die ich generisch machen möchte.
  • Mein Ordner der obersten Ebene enthält oft ein paar andere Dinge, einschließlich, aber nicht beschränkt auf wsgi-Skripte, SQL-Skripte usw.
  • Die Verwaltungserweiterungen von django basieren auf Unterverzeichnissen. Daher ist es sinnvoll, Pakete entsprechend zu benennen.

Kurz gesagt, der Grund, warum es eine Konvention gibt, ist der gleiche wie bei jeder anderen Konvention - es hilft, wenn andere mit Ihrem Projekt arbeiten. Wenn ich sehe, fields.pyerwarte ich sofort, dass der darin enthaltene Code das Feld von Django unterordnet, während ich, wenn ich sehe, inputtypes.pymöglicherweise nicht so klar bin, was das bedeutet, ohne es anzusehen .


quelle
24
+1 ... "Was soll Sie davon abhalten, myproduct.myproduct zu verwenden?" - Djangos "startapp" -Befehl stoppt Sie tatsächlich, nehme ich an, als Konvention. Ich mag Konventionen, besonders im Rahmen einer
Dolph
@ Delph ah, oder? Ich habe es seit meiner ersten Verwendung nicht mehr verwendet, da ich einen eigenen Befehl zum Erstellen eines Projekts habe, das zuerst Modelle erstellt und dann automatisch CRUD-Daten für diese Modelle generiert. Trotzdem sind Konventionen gut. Ich folge Django-Konventionen, schon allein deshalb, weil sie größtenteils Sinn machen.
1
Ich füge hinzu, dass die Verwendung des gleichen Namens für ein Projekt und eine darin enthaltene App ebenfalls Probleme mit manage.pyverursacht und dazu führt, dass Ihre Projekteinstellungen nicht korrekt importiert werden können. Dies ist mir passiert und ich habe es gelöst, indem ich die App entsprechend umgestaltet habe myproduct_app.
BHSPitMonkey
89

Sobald Sie die Verwendung von startprojectund abgeschlossen haben startapp, hindert Sie nichts daran, ein "Projekt" und eine "App" in demselben Python-Paket zu kombinieren. Ein Projekt ist wirklich nichts anderes als ein settingsModul, und eine App ist wirklich nichts anderes als ein modelsModul - alles andere ist optional.

Für kleine Websites ist es völlig vernünftig, etwas zu haben wie:

site/
    models.py
    settings.py
    tests.py
    urls.py
    views.py
Claymation
quelle
18
+1 Zusammenfassung: Projekt hat settings.py, App hat models.py. Sie sind die gleiche Ebenenstruktur. Früher dachte ich, das Projekt sei eine Ebene höher als die App. Ich glaube, ich habe mich geirrt
Philip007
2
@claymation, was sollte in den Einstellungen (als App) enthalten sein, damit "python manage.py makemigrations" oder "python manage.py migrate" die Datei "models.py" im Verzeichnis "my product" anzeigen kann?
mlwn
1
@mlwn Mir ist klar, dass ich sehr spät dran bin, aber ich bin selbst in einer ähnlichen Situation und habe mir viele Antworten angesehen. Um Ihre Frage zu beantworten, müssen Sie lediglich Ihr Projekt in die INSTALLED_APPSListe aufnehmen. Hier ist ein Beispiel: stackoverflow.com/a/59739912/399435
Karthic Raghupathi
@KarthicRaghupathi, Danke .. :) Schön zu sehen, dass Kommentare nach vier Jahren beantwortet werden ..
Prost
69

Versuchen Sie, die Frage zu beantworten: "Was macht meine Bewerbung?". Wenn Sie nicht in einem Satz antworten können, können Sie ihn möglicherweise mit einer saubereren Logik in mehrere Apps aufteilen.

Ich habe diesen Gedanken irgendwo gelesen, kurz nachdem ich angefangen habe, mit Django zu arbeiten, und ich stelle fest, dass ich mir diese Frage ziemlich oft stelle und sie mir hilft.

Ihre Apps müssen nicht wiederverwendbar sein, sie können voneinander abhängen, aber sie sollten eines tun.

Ski
quelle
8
Ich habe immer noch Probleme, meine eigene App zu erstellen. Ich habe das Gefühl, dass meine Hauptanwendung etwas schwer ist, aber gleichzeitig wäre ich nicht in der Lage, sie in etwas umzugestalten, das etwas ähnelt, das lose gekoppelt ist. Ich neige dazu zu denken, dass es nicht wirklich eine Verbesserung wäre, wenn meine Hauptentitäten getrennt würden, wenn sie immer noch stark voneinander abhängen und es keine Notwendigkeit gibt, sie am Horizont wiederzuverwenden oder zu verallgemeinern. Ich neige zu "nicht vorzeitig umgestalten" als Interpretation von "nicht vorzeitig optimieren"
acjay
8

Wenn ja ... in Bezug auf Djangos Projekt.app-Namespace neige ich dazu, ein Produkt zu verwenden. Ein Produkt, aber das ist natürlich nicht erlaubt

Es gibt nichts wie nicht erlaubt. Es ist dein Projekt, niemand schränkt dich ein. Es ist ratsam, einen vernünftigen Namen zu behalten.

Ich sehe keinen Teil meines Produkts, der in irgendeinem Kontext wiederverwendbar ist. Intuitiv würde ich diese eine "Anwendung" nennen. Mache ich dann meine ganze Arbeit in einem einzigen "App" -Ordner?

In einem allgemeinen Django-Projekt gibt es viele Apps (Contrib-Apps), die wirklich in jedem Projekt verwendet werden.

Nehmen wir an, Ihr Projekt erledigt nur eine Aufgabe und hat nur eine einzige App (ich nenne es main nenne da sich das Projekt darum dreht und kaum steckbar ist). Auch dieses Projekt verwendet im Allgemeinen noch einige andere Apps.

Wenn Sie nun sagen, dass Ihr Projekt nur die eine App ( INSTALLED_APPS='myproduct') verwendet, was also zur projectDefinition des Projekts verwendet wird project.app, sollten Sie einige Punkte berücksichtigen:

  • Es gibt viele andere Dinge, die der Code außer der App in einem Projekt behandelt (statische Basisdateien, Basisvorlagen, Einstellungen ... dh die Basis).
  • Im allgemeinen project.app-Ansatz definiert django automatisch das SQL-Schema aus Modellen.
  • Ihr Projekt wäre mit dem herkömmlichen Ansatz viel einfacher zu erstellen.
  • Sie können nach Belieben unterschiedliche Namen für URLs, Ansichten und andere Dateien definieren, aber ich sehe keine Notwendigkeit.
  • Möglicherweise müssen Sie in Zukunft einige Anwendungen hinzufügen, die mit den herkömmlichen Django-Projekten sehr einfach sind. Andernfalls kann die Ausführung gleichermaßen oder schwieriger und langwieriger werden.

Was die meisten Arbeiten in der App betrifft, denke ich, dass dies bei den meisten Django-Projekten der Fall ist.

Crodjer
quelle
1
+1, besonders für die mainConvention - das macht für mich für ein originelles Projekt wie dieses sehr viel Sinn. Ich habe vor, später "wiederverwendbare" Apps hinzuzufügen, aber das liegt momentan weit außerhalb meines Fokus.
Dolph
2

Hier weisen Django-Schöpfer selbst auf diesen Unterschied hin . Ich denke , dass das Denken über Apps wie sie sein müssen , wiederverwendbar in anderen Projekten ist gut . Auch eine gute Denkweise über Apps in Django bietet moderne Webanwendungen.

Stellen Sie sich vor, Sie erstellen eine große dynamische Web-App, die auf JavaScript basiert .

Sie können dann in der Django-App mit dem Namen "FrontEnd" <erstellen. In dieser App werden Inhalte angezeigt.

Dann erstellen Sie einige Backend-Apps. ZB App mit dem Namen "Kommentare", in der Benutzerkommentare gespeichert werden. Und die App "Kommentare" zeigt selbst nichts an. Es ist nur eine API für AJAX-Anforderungen Ihrer dynamischen JS- Website .

Auf diese Weise können Sie Ihre App "Kommentare" jederzeit wiederverwenden. Sie können es Open Source machen, ohne die Quelle des gesamten Projekts zu öffnen. Und Sie halten die Logik Ihres Projekts sauber .

Qback
quelle