Pregunta

Acabo de hacer el trabajo a través de la Django tutoriales para el segundo tiempo, y estoy a la comprensión de las cosas mucho más claro ahora.Sin embargo, todavía estoy claro de cómo las aplicaciones dentro de un sitio de interactuar el uno con el otro.

Por ejemplo, digamos que estoy escribiendo un blog (más bien una actividad muy popular, al parecer).Entradas de Blog y los comentarios tienden a ir juntos, y sin embargo son distintas suficiente que deberían ser construidos en distintas aplicaciones, como es la filosofía general de la Djano desarrollo.

Considere el siguiente ejemplo.En realidad yo no iba a escribir el comentario de la aplicación de mí mismo, como un buen código para la que ya existe en la web, pero este es para la demostración/efectos de la práctica:

mysite/blog/models.py

from django.db import models

class post(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    content = models.TextField()

mysite/comments/models.py

from django.db import models
from mysite.blog.models import post

class comment(models.Model):
    id = models.AutoField()
    post = models.ForeignKey(post)
    author = models.CharField(max_length=200)
    text = models.TextField()

Es lo que escribí anteriormente, la importación de un modelo desde otra aplicación y configurarla como una clave foránea, cómo Django aplicaciones interactuar?O es que hay un diferente/mejor método para las aplicaciones que componen un sitio para interactuar?

Actualización
Por la recomendación de una respuesta, estoy leyendo la documentación de contrib.contenttypes.Si estoy leyendo correctamente, yo podría escribir mi ejemplo de comentario de una aplicación, como este:

from django.db import models  
from django.contrib.contenttypes.models import ContentType
from django.contrib.contentypes import generic

class comment(models.Model):  
    id = models.AutoField()  
    author = models.CharField(max_length=200)  
    text = models.TextField()  
    content_type = models.ForeignKey(ContentType)  
    content_object = generic.GenericForeignKey(content_type, id)  

Podría ser esto correcto?

¿Fue útil?

Solución

Echa un vistazo a django incorporado en contenttypes marco:

django.contrib.contenttypes

Esto le permite desarrollar sus aplicaciones como unidades independientes.Esto es lo que los desarrolladores de django utiliza para permitir django incorporado en comentario de marco para adjuntar un comentario a cualquier modelo en su proyecto.

Por ejemplo, si usted tiene algunos de los objetos de contenido que desea "adjuntar" para otros objetos de contenido de diferentes tipos, como el que permite a cada usuario para dejar un "favorito" de estrellas en una entrada de blog, la imagen o el perfil de usuario, puede crear un Favorite modelo con un genérico de la relación campo así:

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Favorite(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

De esta manera usted puede agregar un Favorite la estrella de cualquier usuario a cualquier modelo en su proyecto.Si desea agregar el acceso a la API a través de los destinatarios de la clase del modelo que usted puede añadir un inversa genérica de la relación campo en el destinatario modelo (aunque esto sería "acoplamiento" los dos modelos, que usted dijo que quería evitar), o hacer la búsqueda a través de la Favorite modelo con el content_type y object_id de que el destinatario ejemplo, ver la oficial docs para un ejemplo.

Otros consejos

" ¿Es lo que escribí anteriormente, importar un modelo desde otra aplicación y configurarlo como una clave externa, cómo interactúan las aplicaciones de Django? "

Sí. Funciona para mí.

Tenemos alrededor de 10 aplicaciones que se prestan de un lado a otro entre ellas.

Esto lleva a una especie de dependencia en nuestro script de prueba de unidad.

Se ve así.

  • " propiedad " ;. Tenemos una aplicación de propiedad de datos simple que define algunos conceptos básicos de propiedad de los que dependen otras aplicaciones. Aquí hay algunas tablas simples.

  • " cosa " ;. [No es el nombre real]. Nuestra aplicación tiene elementos de datos propiedad de diferentes grupos de usuarios. En realidad, hay varias tablas complejas del modelo para esta aplicación. Depende de "ownership".

  • " tablas " ;. [No es el nombre real]. Algunos de nuestros usuarios crean modelos fuera de línea bastante complejos (probablemente con hojas de cálculo) y cargan los resultados de ese modelado en & Quot; tablas & Quot ;. Esto tiene un grupo de tablas bastante complejas. Depende de "ownership".

  • " resultado " ;. [No es el nombre real]. Nuestros resultados se basan en cosas que tienen dueños. Los resultados se basan en cosas y tablas, y son respuestas a las solicitudes de los clientes. Esto no es demasiado complejo, quizás solo dos o tres tablas principales. Depende de & Quot; cosas & Quot; y " table " ;. No, no es completamente independiente. Sin embargo, está sujeto a más cambios que las otras cosas de las que depende. Es por eso que está separado.

  • " procesamiento " ;. Programamos y monitoreamos trabajos de lotes grandes. Esto está en esta aplicación. Es realmente genérico y se puede usar de varias maneras. Está completamente solo.

  • " bienvenido " ;. Tenemos un & Quot; bienvenido & Quot; aplicación que presenta un montón de páginas en su mayoría estáticas. Esto no tiene demasiadas tablas. Pero está en su segunda encarnación porque la primera era demasiado compleja. Está completamente solo.

La única relación entre las aplicaciones dependientes son algunos nombres de tablas. Siempre que conservemos esas tablas (y sus claves) podemos reorganizar otras aplicaciones como mejor nos parezca.

No hay nada malo (en mi humilde opinión) en hacer que una aplicación dependa de otra. Después de todo, las aplicaciones son solo operaciones en un conjunto de modelos. solo tiene que saber siempre qué aplicación depende de qué aplicación (supongo que podría llamarse a eso un mapa de dependencia).

Puede lograr un acoplamiento flexible con el marco de tipos de contenido. Permite que una aplicación sea verdaderamente portátil / enchufable y aún así integrada con otras aplicaciones.

Escribí una aplicación de comentarios (sí, reinventé la rueda), que se puede integrar en cualquier otra aplicación, con unas pocas líneas en la plantilla de la página donde se deben publicar los comentarios (usando etiquetas personalizadas).

Digamos que quiere un modelo " thread " para ser enchufable a cualquier otro modelo. La idea es crear una clave externa genérica (consulte la documentación de django sobre eso) y escribir una pequeña función que tome cualquier objeto y devuelva un & Quot; thread & Quot; correspondiente (o crea una si es necesario) y escribe una etiqueta de plantilla personalizada que use esa funcionalidad, p. {% get_thread for arbitrary_object as thread %}. Todas las publicaciones están relacionadas con un hilo, que está relacionado con el objeto, que puede ser de cualquier tipo.

Puedes pensar en " thread " objeto como una especie de proxy, por lo que en lugar de tener una publicación relacionada con un determinado " artículo " o un " blog post " ;, solo está relacionado con un hilo, que en cierto sentido es abstracto, ¿qué es es un hilo? Es solo una colección de publicaciones. El hilo entonces se permite relacionarse con cualquier objeto independientemente de su tipo. (aunque hace más que eso, podría contener información adicional como permitir / no permitir publicaciones anónimas, cerrar / abrir comentarios en la página, etc.)

EDIT

Aquí se explica cómo puede crear una clave externa genérica con el marco de tipos de contenido:

from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType

class Thread( models.Model ):
    object_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    object = generic.GenericForeignKey('object_type', 'object_id')

Puede hacerlo más " transparente " explotando lo implícito " común " interfaz que django supone que todos los objetos implementan ...

    #inside the Thread class:
    def __unicode__(self):
        return unicode(self.object)
    def get_absolute_url(self):
        return self.object.get_absolute_url()

Su código parece correcto. Sin embargo, mantendría la publicación y el comentario en una aplicación de blog . No digo que sea la forma de Django, pero esos modelos están lo suficientemente cerca como para estar en la misma aplicación.

Cómo dividir el proyecto

Separaría una aplicación si;

  • Planeo diseñarlo de forma valiosa. (e intente el acoplamiento flojo)
  • (para grandes proyectos) Consiste en una sección importante del proyecto.

Por otro lado; tener muchas aplicaciones pequeñas (como una aplicación con un solo modelo y dos vistas) es difícil de leer y mantener en mi humilde opinión.

Cómo deberían interactuar las aplicaciones

Esto depende del tipo de proyecto y del tipo de aplicación nuevamente. Por ejemplo, si una aplicación depende implícitamente de otra importación (es decir, no genérica) y es aceptable utilizar referencias de la otra aplicación. En este caso, la segunda aplicación podría instalarse sola, pero la primera necesita la presencia de la segunda.

Si desea que una aplicación sea altamente reutilizable y genérica, como una aplicación de comentarios, es posible que deba integrar algún mecanismo de configuración. Tal vez algunas nuevas configuraciones o configuración de URL adicional, o una directiva / método especial en sus modelos ... django.contrib.admin es un buen ejemplo de esto.

Sin embargo, las aplicaciones no deberían interactuar si no es necesario. Diseñar aplicaciones para evitar acoplamientos innecesarios es muy útil. Mejora la flexibilidad de su aplicación y la hace más fácil de mantener (pero posiblemente con un mayor costo de integración).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top