python - django tutorial español pdf




Django: ¿cómo desacoplar completamente las aplicaciones cuando parece que están acopladas? (2)

Nota : no soy un programador de python adecuado ... pero uso python ampliamente. Hago cosas como clases de escritura con herencia, uso de iteradores y comprensión, etc. Mi punto es que no tengo un conocimiento completo del lenguaje, por ejemplo, qué constituye exactamente un objeto de python, por __init__.py se necesita __init__.py más que para especificar un módulo, etc. En relación con Django, he escrito sitios de múltiples aplicaciones (con la ayuda de SO) y realmente he disfrutado el sistema de plantillas de Django, los bloques y cómo se pueden anidar. ¿Ahora mis aplicaciones están completamente desacopladas y son reutilizables? Que este es el tema de este post.

Declaro este descargo de responsabilidad porque muchos de los recursos de Django parecen suponer que uno sabe estas cosas. Esto dificulta la comprensión de parte de la documentación y las preguntas de SO para una persona que solo es un usuario (subpotencia). Así que por favor responde esta pregunta con eso en mente.

Pregunta

Estas preguntas están inspiradas en la pregunta ¿ Cuándo crear una nueva aplicación con startapp en django? por @håkan y la answer dada por @antti rasinen que enlaza con la presentación PyCon 2008 de James Bennett

Algunos puntos clave de la presentación de Bennett son:

  1. los sitios son una colección de aplicaciones
  2. Una aplicación hace una cosa y una cosa bien.

Lo que me dirige a su sección "El acoplamiento de proyectos mata la reutilización" que menciona:

  • Módulo único directamente en la ruta de Python (registro, etiquetado, etc.)
  • Módulos relacionados bajo un paquete (ellington.events, ellington.podcasts, etc.)

Pregunta 0

¿Un "módulo" en este caso es solo una aplicación hecha de otras aplicaciones?

Pregunta 1

(Aplicaciones con funcionalidades relacionadas y modelos compartidos).

¿Qué debo hacer cuando las aplicaciones comparten modelos?

En las diapositivas de Barrett, él implica que el registro de usuario y los perfiles de usuario son distintos y deberían ser aplicaciones distintas. (Sin duda, afirma que los perfiles no tienen nada que ver con el registro de usuarios).

Entonces, si quisiera ambos, mi proyecto tendría dos aplicaciones como:

  • registro de usuario
  • perfil del usuario

¿Aunque el user-profile la aplicación necesitará el modelo de user-registration de user-registration ? O hago una sola aplicación ( module ):

  • aplicación de usuario
    • registro
    • perfil

que contiene ambos?

Pregunta 2

(Aplicaciones con distintas funciones pero modelos compartidos).

Extendiendo el ejemplo de la pregunta 1, digamos que mi aplicación principal (o alguna otra aplicación utilizada por la aplicación principal) utiliza algún aspecto del modelo de usuario (por ejemplo, miembros recientemente activos si era un sitio de chat).

Claramente, mi aplicación principal obtiene esta información del modelo de usuario. ¿Mi aplicación principal ahora se incluye en el módulo de user-app ?

Este puede no ser el mejor ejemplo, pero el punto es el siguiente:

Tengo dos aplicaciones app-dependency app-needs-dependency y app-dependency app-needs-dependency , donde cada aplicación hace su única cosa y otra bien ... Es solo que app-needs-dependency necesidades de la app-dependency necesita información de app-dependency de la app-dependency . ¿Qué hago en este caso, si todo lo relacionado app-needs-dependency está completamente separado de app-dependency de la app-dependency (por lo que podría usarse en otros proyectos)?

Pregunta 3

(aplicaciones de escritura para la flexibilidad)

Ahora tengo mi sitio con su par de aplicaciones. Cada aplicación hace su única cosa y lo hace bien. La aplicación principal sirve como página de inicio / descripción general en este caso.

Quiero que todas mis otras aplicaciones utilicen / hereden los archivos estáticos y de plantilla de la aplicación principal.

¿Dónde almaceno todos los archivos y plantillas estáticos? ¿En la aplicación principal y configurarlo como predeterminado para las otras aplicaciones? ¿O a dónde deben ir estos archivos / plantillas estáticos (por ejemplo, base.html , base.html )? ¿Hago una copia de estos archivos para cada aplicación, de modo que puedan ejecutarse aunque esto sea redundante?

¿Qué hace que mi aplicación sea más flexible?


Pregunta 0

Un "módulo" en el contexto de Python es simplemente un archivo que contiene definiciones y declaraciones. Así que "los módulos relacionados en un paquete" realmente solo significa "dividir el código en archivos separados según lo que esté haciendo el código".

Describirlo como "una aplicación hecha de otras aplicaciones" es comenzar a confundir el concepto de Django de una aplicación con el concepto de Python de un módulo (que, como se indicó anteriormente, es solo un archivo que contiene algún código).

Pregunta 1

¿Qué debo hacer cuando las aplicaciones comparten modelos?

Aún debe intentar y atenerse a la máxima de "las aplicaciones hacen una cosa y la hacen bien". En este caso, las aplicaciones de perfil y registro separadas parecen una buena idea, ya que tienen funciones muy diferentes. Una aplicación de registro contendrá la lógica para permitir a los usuarios registrarse en su sitio. Una aplicación de perfil tiene que ver con la información que almacenará sobre un usuario.

No hay nada de malo en que estas dos aplicaciones tengan una relación entre sí, ver más abajo.

Pregunta 2

Digamos que mi aplicación principal (o alguna otra aplicación utilizada por la aplicación principal) utiliza algún aspecto del modelo de usuario (por ejemplo, miembros activos recientemente si era un sitio de chat). Claramente, mi aplicación principal obtiene esta información del modelo de usuario. ¿Mi aplicación principal ahora se incluye en la aplicación de usuario?

No. Todavía debería ser una aplicación separada, con enlaces a la otra aplicación.

El modelo de usuario es en realidad un buen ejemplo. Django le permite especificar un modelo de usuario personalizado que le permite almacenar cualquier información adicional que desee sobre un usuario.

Ahora, hay un montón de aplicaciones de terceros que hacen cosas como registro, autenticación, etc. para los usuarios. Están diseñados para funcionar con cualquier modelo de usuario, no solo con el predeterminado de Django. La forma en que lo hacen es usar get_user_model() donde sea necesario para hacer referencia al modelo de User , en lugar de importar directamente django.contrib.auth.models.User .

Esto significa que puede usar esas aplicaciones de terceros con cualquier modelo de usuario que haya definido para su propio proyecto.

La utilidad get_user_model() Django está ahí para servir un caso de uso muy común. Sin embargo, el mismo principio puede extenderse a sus propias aplicaciones. Si hay una dependencia entre sus aplicaciones que cree que debería ser intercambiable, entonces puede proporcionar una manera de intercambiarla, por ejemplo, una configuración / configuración que permita que cualquier otro proyecto que use su aplicación especifique una alternativa.

Hay cientos de ejemplos de este tipo de configurabilidad en el ecosistema de Django. Por ejemplo, Django se entrega con su propia aplicación de autenticación django.contrib.auth . Sin embargo, si desea implementar su propia lógica de autenticación, no tiene que volver a implementar la aplicación de autenticación completa (eso sería un gran dolor). En su lugar, especifica un backend de autenticación que su aplicación de autenticación usará para autenticarse. La aplicación auth está diseñada para permitir que cualquier proyecto intercambie una parte central de su funcionalidad con un mínimo esfuerzo.

Por lo tanto, en su aplicación main , puede definir una configuración que controle qué modelo de profile usar. Esto significa que si alguien más quiere usar un modelo de perfil diferente, simplemente cambian esta configuración y están configurados. Ya no están vinculados a su aplicación de profile .

Por ejemplo, supongamos que tiene una aplicación main que tiene una vista que muestra algunos datos de usuario, pero que también proporciona un enlace a una vista de registro proporcionada por una aplicación diferente. Desea que cualquier otra persona pueda usar esa aplicación, independientemente de la aplicación de registro que esté utilizando. Para que pueda hacer que esta vista sea tan valiosa como:

En main/views.py :

from django.contrib.auth import get_user_model
from django.conf import settings
from django.urls import reverse

class UserDetailView(DetailView):

    # First of all, we're using get_user_model so that a project
    # can specify whatever user model it wants, and still use this
    # view.
    model = get_user_model()

    def get_context_data(self, *args, *kwargs):
        ctx = super().get_context_data(*args, **kwargs)
        # We want to add a link to a registration view into this template context.
        # But we want this to be configurable.
        # Your REGISTRATION_URL would be something like 'profile:registration'
        ctx['registration_link'] = reverse(settings.REGISTRATION_URL)
        return ctx

Pregunta 3

La aplicación principal sirve como página de inicio / descripción general en este caso. Quiero que todas mis otras aplicaciones utilicen / hereden los archivos estáticos y de plantilla de la aplicación principal. ¿Dónde almaceno todos los archivos y plantillas estáticos?

Debe almacenar las plantillas en cada aplicación respectiva. Si su aplicación principal proporciona las plantillas base, entonces esas deberían residir en la aplicación principal.

Si su aplicación de perfil proporciona una vista de registro, la plantilla para eso debe estar en la aplicación de perfil. No hay nada de malo en que extienda la plantilla base desde la aplicación principal, esto puede ser fácilmente anulado por un proyecto que lo desee.

Está bien hacer suposiciones acerca de cómo se relacionan dos aplicaciones entre sí, siempre y cuando sea cuidadoso para permitir la anulación de esas suposiciones.


Debo admitir que su pregunta no es técnica, sino conceptual y dogmática. Ninguna respuesta es absoluta y universalmente válida, y todos los detalles sobre cómo se proyecta y cómo debe comportarse su proyecto pueden cambiar la perspectiva. Como escribiste, cada aplicación Django hace una cosa y lo hace bien.

Lo extendería hasta el punto de que cada aplicación no debe contener más de un Model y, como máximo, son dependientes de los armarios.

Ej: el Product con su Category , Color , Image

Tendrás mucha lógica para cubrir dentro de esa aplicación solo con estas.

Intente ver el marco de Django como una herramienta para crear su proyecto ... este es el objetivo final ... pero si también desea crear aplicaciones reutilizables, intente crearlas de la forma más independiente posible, o al menos dependiente de algunas características de Django:

Por ejemplo: una aplicación reutilizable y totalmente independiente sería una aplicación que solo requiere Modelo de User , Sessions , Groups incluidos en Django. Tienes la idea de una aplicación dependent pero aún autónoma.

Una app es parte de un proyecto después de todo ... ya sea aquí o en otra parte después de construirla. Míralo como si fuera una función simple ... puede ejecutarse solo o puede depender del resultado de otras funciones ... en qué punto mantienes todo dentro de una función y cuando decides dividirlas en 2 funciones distintas. Asi que:

  • Pregunta 0:

    Una aplicación es la pieza más pequeña que se puede ejecutar por sí misma ... con modelos, vistas, plantillas, URL, archivos estáticos.

    Puede depender también de otras aplicaciones ... así que la respuesta es SÍ

  • Pregunta 1:

    Siempre mantenga las cosas separadas por la funcionalidad ... User Auth se ocupa de la creación de usuarios y su autenticación

    El perfil de usuario trata con datos personales del usuario

  • Pregunta 2:

    Nada se lía. Todo se mantiene al mismo nivel que 2 aplicaciones diferentes pero dependientes.

  • Pregunta 3:

    Puedes hacer lo que quieras.

    Puede hacer estática como lugar central y plantillas específicas para cada aplicación o todo lo que sea central. No hay una respuesta correcta aquí, solo lo que se adapta bien a su proyecto.





django