Instrucciones de mi supervisor: "Quiero evitar poner cualquier lógica en models.py. De ahora en adelante, usemos eso como solo clases para acceder a la base de datos, y mantengamos toda la lógica en las clases externas que usan las clases de modelos, o las envuelven".

Siento que este es el camino equivocado. Siento que mantener la lógica fuera de los modelos solo para mantener el archivo pequeño es una mala idea. Si la lógica es mejor en el modelo, ahí es donde realmente debería ir, independientemente del tamaño del archivo.

Entonces, ¿hay una manera simple de usar solo incluye? En PHP-speak, me gustaría proponerle al supervisor que simplemente models.py incluya () las clases modelo de otros lugares. Conceptualmente, esto permitiría a los modelos tener toda la lógica que deseamos, pero mantener el tamaño de archivo bajo al aumentar el número de archivos (lo que conduce a menos problemas de control de revisión como conflictos, etc.).

Entonces, ¿hay una manera simple de eliminar clases de modelos del archivo models.py, pero aún así los modelos funcionan con todas las herramientas de Django? ¿O hay una solución completamente diferente pero elegante para el problema general de un archivo "grande" de models.py? Cualquier aportación sería apreciada.

91
Eddified 21 jul. 2009 a las 21:27

2 respuestas

La mejor respuesta

Django está diseñado para permitirle construir muchas aplicaciones pequeñas en lugar de una gran aplicación.

Dentro de cada aplicación grande hay muchas aplicaciones pequeñas que luchan por ser gratuitas.

Si tu models.py se siente grande, estás haciendo demasiado. Detener. Relajarse. Descomponer.

Encuentre piezas o componentes de aplicaciones pequeñas más pequeños y potencialmente reutilizables. No tiene que realmente reutilizarlos. Solo piense en ellos como potencialmente reutilizables.

Considere sus rutas de actualización y descomponga las aplicaciones que tal vez desee reemplazar algún día. No tiene que realmente reemplazarlos, pero puede considerarlos como un "módulo" de programación independiente que podría reemplazarse por algo más genial en el futuro.

Tenemos alrededor de una docena de aplicaciones, cada model.py no tiene más de aproximadamente 400 líneas de código. Todos están bastante centrados en menos de media docena de definiciones de clase discretas. (Estos no son límites estrictos, son observaciones sobre nuestro código).

Nos descomponemos temprano y con frecuencia.

63
Peter Mortensen 30 ene. 2010 a las 16:57

Es natural que las clases de modelo contengan métodos para operar en el modelo. Si tengo un modelo de Libro, con un método book.get_noun_count(), ahí es donde pertenece: no quiero tener que escribir "get_noun_count(book)", a menos que el método realmente intrínsecamente pertenezca a algún otro paquete. (Podría, por ejemplo, si tengo un paquete para acceder a la API de Amazon con "get_amazon_product_id(book)").

Me estremecí cuando la documentación de Django sugirió poner modelos en un solo archivo, y me tomé unos minutos desde el principio para descubrir cómo dividirlo en un subpaquete adecuado.

site/models/__init__.py
site/models/book.py

__init__.py se ve así:

from .book import Book

Así que todavía puedo escribir "from site.models import Book".


Lo siguiente solo es necesario para versiones anteriores a Django 1.7, consulte https://code.djangoproject.com/ticket/3591

El único truco es que necesita configurar explícitamente la aplicación de cada modelo, debido a un error en Django: se supone que el nombre de la aplicación es la penúltima entrada en la ruta del modelo. "site.models.Book" da como resultado "site", que es correcto; "site.models.book.Book" hace pensar que el nombre de la aplicación es "modelos". Este es un truco bastante desagradable por parte de Django; probablemente debería buscar en la lista de aplicaciones instaladas una coincidencia de prefijo.

class Book(models.Model):
    class Meta: app_label = "site"

Probablemente podría usar una clase base o metaclase para generalizar esto, pero aún no me he molestado con eso.

103
jonrsharpe 8 ago. 2015 a las 07:06