Django: «projets» vs «applications»

202

J'ai un "produit" assez complexe que je me prépare à construire avec Django. Je vais éviter d'utiliser les termes "projet" et "application" dans ce contexte, car je ne suis pas clair sur leur signification spécifique dans Django.

Les projets peuvent avoir de nombreuses applications. Les applications peuvent être partagées entre de nombreux projets. Bien.

Je ne réinvente pas le blog ou le forum - je ne vois aucune portion de mon produit réutilisable dans n'importe quel contexte. Intuitivement, j'appellerais celle-ci «application». Dois-je ensuite faire tout mon travail dans un seul dossier "app"?

Si c'est le cas ... en termes d' project.appespace de noms de Django , mon inclination est d'utiliser myproduct.myproduct, mais bien sûr ce n'est pas autorisé (mais l'application que je construis est mon projet, et mon projet est une application!). Je suis donc amené à croire que je suis peut-être censé approcher Django en créant une application par modèle "significatif", mais je ne sais pas où tracer les limites de mon schéma pour le séparer en applications - j'en ai beaucoup de modèles avec des relations relativement complexes.

J'espère qu'il y a une solution commune à cela ...

Dolph
la source
1
Les documents expliquent la différence entre "application" et "projet" ici: docs.djangoproject.com/en/dev/ref/applications/…
guettli

Réponses:

56

Qu'est-ce qui vous empêche d'utiliser myproduct.myproduct? Ce dont vous avez besoin pour y parvenir consiste grosso modo à faire ceci:

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

etc. Serait-il utile que je dise views.pyqu'il ne faut pas appeler views.py? À condition que vous puissiez nommer, sur le chemin python, une fonction (généralement package.package.views.function_name) qu'elle sera gérée. Aussi simple que cela. Tous ces trucs «projet» / «app» ne sont que des paquets python.

Maintenant, comment êtes-vous censé le faire? Ou plutôt, comment pourrais-je le faire? Eh bien, si vous créez un élément important de fonctionnalités réutilisables, comme dire un éditeur de balisage, qui est lorsque vous créez une « application de haut niveau » qui pourrait contenir widgets.py, fields.py, context_processors.pyetc. - toutes les choses que vous voudrez peut - être importer.

De même, si vous pouvez créer quelque chose comme un blog dans un format assez générique entre les installations, vous pouvez le terminer dans une application, avec son propre modèle, un dossier de contenu statique, etc., et configurer une instance d'un projet django pour l'utiliser. le contenu de l'application.

Il n'y a pas de règles strictes et rapides disant que vous devez le faire, mais c'est l'un des objectifs du cadre. Le fait que tout, y compris les modèles, vous permet d'inclure à partir d'une base commune signifie que votre blog doit s'intégrer parfaitement dans toute autre configuration, simplement en prenant soin de sa propre partie.

Cependant, pour répondre à votre préoccupation réelle, rien ne dit que vous ne pouvez pas travailler avec le dossier de projet de niveau supérieur. C'est ce que font les applications et vous pouvez le faire si vous le souhaitez vraiment. Cependant, je n'ai pas tendance à le faire pour plusieurs raisons:

  • La configuration par défaut de Django ne le fait pas.
  • Souvent, je veux créer une application principale, donc j'en crée une, généralement appelée website. Cependant, à une date ultérieure, je souhaiterais peut-être développer des fonctionnalités originales uniquement pour ce site. En vue de le rendre amovible (que je le fasse ou non), j'ai tendance à créer un répertoire séparé. Cela signifie également que je peux supprimer cette fonctionnalité simplement en dissociant ce package de la configuration et en supprimant le dossier, plutôt que de supprimer de manière complexe les bonnes URL d'un dossier global urls.py.
  • Très souvent, même quand je veux faire quelque chose d'indépendant, il a besoin d'un endroit pour vivre pendant que je le soigne / je le rend indépendant. Fondamentalement, le cas ci-dessus, mais pour les choses que j'ai l'intention de faire génériques.
  • Mon dossier de niveau supérieur contient souvent quelques autres éléments, y compris, mais sans s'y limiter, les scripts wsgi, les scripts sql, etc.
  • Les extensions de gestion de django reposent sur des sous-répertoires. Il est donc logique de nommer les packages de manière appropriée.

En bref, la raison pour laquelle il existe une convention est la même que n'importe quelle autre convention - cela aide quand il s'agit d'autres personnes travaillant avec votre projet. Si je vois, fields.pyje m'attends immédiatement à ce qu'il contienne du code pour sous-classer le champ de django, alors que si je vois, inputtypes.pyje ne serais peut-être pas aussi clair sur ce que cela signifie sans le regarder.


la source
24
+1 ... "Qu'est-ce qui vous empêche d'utiliser myproduct.myproduct?" - La commande "startapp" de Django vous arrête en fait, je suppose, comme une convention. J'aime les conventions, en particulier dans le contexte d'un effort d'équipe, mais je préfère comprendre la logique derrière elles :)
Dolph
@Dolph ah, n'est-ce pas? Je ne l'ai pas utilisé depuis la première fois que je l'ai utilisé parce que j'ai ma propre commande pour créer un projet qui crée d'abord des modèles, puis génère automatiquement des éléments CRUD pour ces modèles. Pourtant, oui, les conventions sont bonnes. Je respecte les conventions django, ne serait-ce que parce qu'elles parlent largement, elles ont du sens.
1
J'ajouterai que l'utilisation du même nom pour un projet et une application dans celui-ci pose également des problèmes manage.py, ce qui l'empêche d'importer correctement les paramètres de votre projet. Cela m'est arrivé, et je l'ai résolu en refactorisant l'application à l'effet de myproduct_app.
BHSPitMonkey
89

Une fois que vous avez terminé l'utilisation de startprojectet startapp, rien ne vous empêche de combiner un "projet" et une "application" dans le même package Python. Un projet n'est vraiment rien de plus qu'un settingsmodule, et une application n'est vraiment rien de plus qu'un modelsmodule - tout le reste est facultatif.

Pour les petits sites, il est tout à fait raisonnable d'avoir quelque chose comme:

site/
    models.py
    settings.py
    tests.py
    urls.py
    views.py
claymation
la source
18
+1 Résumé: le projet a settings.py, l'application a models.py. Ils ont la même structure de niveaux. Je pensais que le projet est un niveau plus élevé que l'application, je suppose que j'avais tort
Philip007
2
@claymation, qu'est-ce qui devrait être inclus dans les paramètres (en tant qu'application) afin de permettre à 'python manage.py makemigrations' ou 'python manage.py migrate' de voir le fichier 'models.py' dans le répertoire 'my product'?
mlwn
1
@mlwn Je me rends compte que je suis très en retard pour répondre à cette question, mais je suis moi-même dans une situation similaire et j'ai cherché beaucoup de réponses. Pour répondre à votre question, il vous suffit d'inclure votre projet dans la INSTALLED_APPSliste. Voici un exemple: stackoverflow.com/a/59739912/399435
Karthic Raghupathi
@KarthicRaghupathi, merci .. :) agréable de voir les commentaires répondus après quatre ans .. cheers
mlwn
69

Essayez de répondre à la question: "Que fait mon application?". Si vous ne pouvez pas répondre en une seule phrase, vous pouvez peut-être le diviser en plusieurs applications avec une logique plus propre.

J'ai lu cette pensée quelque part peu de temps après avoir commencé à travailler avec Django et je trouve que je me pose cette question assez souvent et cela m'aide.

Vos applications n'ont pas besoin d'être réutilisables, elles peuvent dépendre les unes des autres, mais elles devraient faire une chose.

Ski
la source
8
Je me bats encore un peu quand il s'agit de créer ma propre application. J'ai l'impression que mon application principale est un peu lourde, mais en même temps, je ne serais pas en mesure de la refactoriser en quelque chose qui ressemble à quelque chose de vaguement couplé. Je penche pour penser que ce ne serait pas vraiment une amélioration d'avoir mes principales entités principales séparées, si elles dépendent encore fortement les unes des autres, et il n'est pas nécessaire de réutiliser ou de généraliser à l'horizon. Je penche vers "ne pas refaire prématurément" comme une interprétation de "ne pas optimiser prématurément"
acjay
8

Si c'est le cas ... en termes d'espace de noms de project.app de Django, mon inclination est d'utiliser usemyproduct.myproduct, mais bien sûr, ce n'est pas autorisé

Il n'y a rien de tel que non autorisé. C'est votre projet, personne ne vous restreint. Il est conseillé de garder un nom raisonnable.

Je ne vois aucune portion de mon produit réutilisable dans n'importe quel contexte. Intuitivement, j'appellerais celle-ci «application». Dois-je ensuite faire tout mon travail dans un seul dossier "app"?

Dans un projet Django général, il existe de nombreuses applications (applications contrib) qui sont vraiment utilisées dans chaque projet.

Disons que votre projet ne fait qu'une seule tâche et n'a qu'une seule application (je le nomme maincar le projet tourne autour de lui et est à peine enfichable). Ce projet utilise également toujours d'autres applications en général.

Maintenant, si vous dites que votre projet utilise uniquement la seule application ( INSTALLED_APPS='myproduct'), alors à quoi sert de projectdéfinir le projet en tant que project.app, je pense que vous devriez considérer certains points:

  • Il y a beaucoup d'autres choses que le code autre que l'application dans un projet gère (fichiers statiques de base, modèles de base, paramètres ... c'est-à-dire fournit la base).
  • Dans l'approche générale de project.app, django définit automatiquement le schéma sql à partir des modèles.
  • Votre projet serait beaucoup plus facile à construire avec l'approche conventionnelle.
  • Vous pouvez définir des noms différents pour les URL, les vues et autres fichiers comme vous le souhaitez, mais je ne vois pas la nécessité.
  • Vous devrez peut-être ajouter à l'avenir des applications, ce qui serait très facile avec les projets django conventionnels, sinon cela pourrait devenir tout aussi ou plus difficile et fastidieux à faire.

En ce qui concerne la plupart du travail effectué dans l'application, je pense que c'est le cas avec la plupart des projets django.

crodjer
la source
1
+1, en particulier pour la mainconvention - cela a beaucoup de sens pour moi pour un projet original comme celui-ci. Je prévois d'ajouter des applications "réutilisables" plus tard, mais c'est en dehors de mon objectif en ce moment.
Dolph
2

Ici, les créateurs de Django soulignent eux-mêmes cette différence . Je pense que la réflexion sur Apps comme ils doivent être réutilisables dans d' autres projets est bon . Une bonne façon de penser aux applications dans Django fournit également des applications Web modernes.

Imaginez que vous créez une grande application Web dynamique basée sur JavaScript .

Vous pouvez ensuite créer dans l'application django nommée par exemple "FrontEnd" <- dans l'application fine, vous afficherez le contenu.

Ensuite, vous créez des applications backend. Par exemple, une application nommée "Commentaires" qui stockera les commentaires des utilisateurs. Et l'application "Commentaires" n'affichera rien elle-même. Ce sera juste une API pour les demandes AJAX de votre site Web JS dynamique .

De cette façon, vous pouvez toujours réutiliser votre application "Commentaires". Vous pouvez le rendre open source sans ouvrir la source de l'ensemble du projet. Et vous gardez une logique propre de votre projet.

Qback
la source