Django: "proyectos" vs "aplicaciones"

202

Tengo un "producto" bastante complejo que estoy preparando para construir usando Django. Voy a evitar el uso de los términos "proyecto" y "aplicación" en este contexto, porque no tengo claro su significado específico en Django.

Los proyectos pueden tener muchas aplicaciones. Las aplicaciones se pueden compartir entre muchos proyectos. Multa.

No estoy reinventando el blog o el foro: no veo que ninguna parte de mi producto sea reutilizable en ningún contexto. Intuitivamente, llamaría a esta "aplicación". ¿Entonces hago todo mi trabajo en una sola carpeta de "aplicación"?

Si es así ... en términos del project.appespacio de nombres de Django , mi inclinación es usar myproduct.myproduct, pero por supuesto esto no está permitido (¡pero la aplicación que estoy construyendo es mi proyecto, y mi proyecto es una aplicación!). Por lo tanto, creo que tal vez se supone que debo acercarme a Django creando una aplicación por modelo "significativo", pero no sé dónde dibujar los límites en mi esquema para separarlo en aplicaciones. Tengo mucho de modelos con relaciones relativamente complejas.

Espero que haya una solución común para esto ...

Dolph
fuente
1
Los documentos explican la diferencia entre "aplicación" y "proyecto" aquí: docs.djangoproject.com/en/dev/ref/applications/…
guettli

Respuestas:

56

¿Qué es para dejar de usar myproduct.myproduct? Lo que necesita para lograr eso consiste aproximadamente en hacer esto:

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

y así. ¿Ayudaría si dijera views.pyque no tiene que ser llamado views.py? Siempre que pueda nombrar, en la ruta de Python, una función (generalmente package.package.views.function_name) que se manejará. Simple como eso. Todas estas cosas de "proyecto" / "aplicación" son solo paquetes de Python.

Ahora, ¿cómo se supone que debes hacerlo? O más bien, ¿cómo podría hacerlo? Bueno, si se crea una pieza importante de la funcionalidad reutilizable, como decir un editor de marcado, que es cuando se crea una "aplicación de nivel superior" que podría contener widgets.py, fields.py, context_processors.pyetc - todas las cosas que usted puede ser que desee importar.

Del mismo modo, si puede crear algo como un blog en un formato que es bastante genérico en todas las instalaciones, puede envolverlo en una aplicación, con su propia plantilla, carpeta de contenido estático, etc., y configurar una instancia de un proyecto django para usarlo contenido de la aplicación

No existen reglas estrictas que indiquen que debe hacer esto, pero es uno de los objetivos del marco. El hecho de que todo, incluidas las plantillas, le permite incluir desde una base común significa que su blog debe encajar perfectamente en cualquier otra configuración, simplemente cuidando su propia parte.

Sin embargo, para abordar su preocupación real, sí, nada dice que no pueda trabajar con la carpeta de proyecto de nivel superior. Eso es lo que hacen las aplicaciones y puedes hacerlo si realmente quieres. Sin embargo, tiendo a no hacerlo por varias razones:

  • La configuración predeterminada de Django no lo hace.
  • A menudo, quiero crear una aplicación principal, así que creo una, generalmente llamada website. Sin embargo, en una fecha posterior me gustaría desarrollar una funcionalidad original solo para este sitio. Con el fin de hacerlo extraíble (ya sea que lo haga o no), tiendo a crear un directorio separado. Esto también significa que puedo eliminar dicha funcionalidad simplemente desvinculando ese paquete de la configuración y eliminando la carpeta, en lugar de eliminar un complejo las URL correctas de una carpeta global urls.py.
  • Muy a menudo, incluso cuando quiero hacer algo independiente, necesita un lugar para vivir mientras lo cuido / lo hago independiente. Básicamente el caso anterior, pero para cosas que tengo la intención de hacer genérico.
  • Mi carpeta de nivel superior a menudo contiene algunas otras cosas, que incluyen, entre otras, scripts wsgi, scripts sql, etc.
  • Las extensiones de administración de django se basan en subdirectorios. Por lo tanto, tiene sentido nombrar los paquetes de manera adecuada.

En resumen, la razón por la que hay una convención es la misma que cualquier otra convención: ayuda cuando se trata de que otros trabajen con su proyecto. Si lo veo fields.py, inmediatamente espero que el código en él subclasifique el campo de django, mientras que si lo veo inputtypes.py, podría no ser tan claro sobre lo que eso significa sin mirarlo.


fuente
24
+1 ... "¿Qué es lo que te impide usar myproduct.myproduct?" - El comando "startapp" de Django realmente te detiene, supongo, como una convención. Me gustan las convenciones, especialmente en el contexto de un esfuerzo de equipo, pero prefiero entender la lógica detrás de ellas :)
Dolph
@Dolph ah, ¿verdad? No lo he usado desde la primera vez que lo usé porque tengo mi propio comando para crear un proyecto que primero crea modelos y luego genera automáticamente CRUD para estos modelos. Aún así, sí, las convenciones son buenas. Sigo las convenciones de django aunque solo sea porque en gran medida tienen sentido.
1
Agregaré que usar el mismo nombre para un proyecto y una aplicación dentro de él también causa problemas manage.py, por lo que no puede importar la configuración de su proyecto correctamente. Esto me sucedió a mí y lo resolví refactorizando la aplicación en el sentido de myproduct_app.
BHSPitMonkey
89

Una vez que te gradúes de usar startprojecty startapp, no hay nada que te impida combinar un "proyecto" y una "aplicación" en el mismo paquete de Python. Un proyecto no es más que un settingsmódulo, y una aplicación no es más que un modelsmódulo; todo lo demás es opcional.

Para sitios pequeños, es completamente razonable tener algo como:

site/
    models.py
    settings.py
    tests.py
    urls.py
    views.py
plastilina
fuente
18
Resumen de +1: el proyecto tiene settings.py, la aplicación tiene models.py. Son la misma estructura de nivel. Yo solía pensar que el proyecto es un nivel más alto que la aplicación, supongo que estaban equivocados
Philip007
2
@claymation, ¿qué se debe incluir en la configuración (como aplicación) para permitir que 'python manage.py makemigrations' o 'python manage.py migrate' vean el archivo 'models.py' en el directorio 'mi producto'?
mlwn
1
@mlwn Me doy cuenta de que llegué muy tarde a responder esto, pero yo mismo estoy en una situación similar y he estado buscando muchas respuestas. Para responder a su pregunta, todo lo que necesita hacer es incluir su proyecto en la INSTALLED_APPSlista. Aquí hay un ejemplo: stackoverflow.com/a/59739912/399435
Karthic Raghupathi
@KarthicRaghupathi, gracias ... :) es bueno ver los comentarios que se responden después de cuatro años ... saludos
mlwn
69

Intente responder la pregunta: "¿Qué hace mi aplicación?". Si no puede responder en una sola oración, tal vez pueda dividirla en varias aplicaciones con una lógica más limpia.

Leí este pensamiento en algún lugar poco después de comenzar a trabajar con django y descubro que me hago esta pregunta con bastante frecuencia y me ayuda.

Sus aplicaciones no tienen que ser reutilizables, pueden depender unas de otras, pero deben hacer una cosa.

Esquí
fuente
8
Todavía estoy luchando un poco cuando se trata de diseñar mi propia aplicación. Siento que mi aplicación principal es un poco pesada, pero al mismo tiempo, no sería capaz de refactorizarla para que se parezca a algo que esté débilmente acoplado. Me inclino a pensar que realmente no sería una mejora separar mis principales entidades principales, si todavía dependen en gran medida unas de otras, y no hay necesidad de reutilizarlas o generalizarlas en el horizonte. Me estoy inclinando hacia "no refactorice prematuramente" como una interpretación de "no optimice prematuramente"
acjay
8

Si es así ... en términos del espacio de nombres project.app de Django, mi inclinación es usar myproduct.myproduct, pero por supuesto esto no está permitido

No hay nada como no permitido. Es tu proyecto, nadie te está restringiendo. Es aconsejable mantener un nombre razonable.

No veo ninguna parte de mi producto reutilizable en ningún contexto. Intuitivamente, llamaría a esta "aplicación". ¿Entonces hago todo mi trabajo en una sola carpeta de "aplicación"?

En un proyecto general de django hay muchas aplicaciones (aplicaciones contrib) que se usan realmente en cada proyecto.

Digamos que su proyecto solo realiza una tarea y tiene una sola aplicación (lo llamo porque el mainproyecto gira en torno a él y apenas es conectable). Este proyecto también todavía usa algunas otras aplicaciones en general.

Ahora, si dice que su proyecto usa solo una aplicación ( INSTALLED_APPS='myproduct'), entonces, ¿de qué sirve projectdefinir el proyecto project.app? Creo que debería considerar algunos puntos:

  • Hay muchas otras cosas que maneja el código que no sea la aplicación en un proyecto (archivos estáticos base, plantillas base, configuraciones ... es decir, proporciona la base).
  • En el enfoque general project.app, django define automáticamente el esquema sql de los modelos.
  • Su proyecto sería mucho más fácil de construir con el enfoque convencional.
  • Puede definir algunos nombres diferentes para las URL, las vistas y otros archivos como desee, pero no veo la necesidad.
  • Es posible que deba agregar algunas aplicaciones en el futuro, lo que sería realmente fácil con los proyectos convencionales de django, que de lo contrario se volverían igual o más difíciles y tediosos de hacer.

En lo que respecta a la mayor parte del trabajo que se realiza en la aplicación, creo que ese es el caso con la mayoría de los proyectos de django.

crodjer
fuente
1
+1, especialmente para la mainconvención, eso tiene mucho sentido para un proyecto original como este. Planeo agregar aplicaciones "reutilizables" más adelante, pero eso está fuera de mi enfoque en este momento.
Dolph
2

Aquí los creadores de Django señalan esa diferencia ellos mismos . Creo que pensar en las aplicaciones, ya que tienen que ser reutilizables en otros proyectos, es bueno . También una buena forma de pensar acerca de las aplicaciones en Django proporciona aplicaciones web modernas.

Imagine que está creando una gran aplicación web dinámica basada en JavaScript .

Puede crear luego en la aplicación django llamada, por ejemplo, "FrontEnd" <- en la aplicación Thins, mostrará contenido.

Luego creas algunas aplicaciones de back-end. Por ejemplo, la aplicación denominada "Comentarios" que almacenará los comentarios de los usuarios. Y la aplicación "Comentarios" no mostrará nada en sí. Será solo API para solicitudes AJAX de su sitio web dinámico JS .

De esta manera, siempre puede reutilizar su aplicación "Comentarios". Puede hacerlo de código abierto sin abrir el código fuente de todo el proyecto. Y mantienes una lógica limpia de tu proyecto.

Qback
fuente