2009-05-21 19 views
21

estoy en el medio del desarrollo de una aplicación Django, que cuenta con modelos muy complicados (modela una universidad - cursos, módulos, clases, estudiantes, etc.)Django App Dependencia Ciclo

he separado el proyecto en aplicaciones , para que todo esté más organizado (las aplicaciones son cursos, escuelas, personas, módulos y timeperiods). Tengo un problema por el cual un modelo en una aplicación puede depender de un modelo en otro, así que debo importarlo. La segunda aplicación, a su vez, depende de un modelo en la primera, por lo que hay un ciclo y Python arroja un error.

¿Cómo lidian las personas con esto? Entiendo que las aplicaciones deben ser relativamente "independientes", pero en un sistema como este no tiene sentido, por ejemplo, usar ContentTypes para vincular a los estudiantes a un módulo.

¿Alguien tiene un proyecto similar que podría comentar sobre este caso?

+0

Su situación no suena como una que las aplicaciones fueron hechas para. La idea de las aplicaciones es la reutilización (junto con el empaquetado, la distribución y el control de versiones por separado). Puede ahorrarse un poco de molestia al no forzar sus áreas temáticas en aplicaciones separadas. –

Respuesta

52

Si su dependencia es con claves externas que hacen referencia a modelos en otras aplicaciones, no necesita para importar el otro modelo. Puede utilizar una cadena en su definición ForeignKey:

class MyModel(models.Model): 
    myfield = models.ForeignKey('myotherapp.MyOtherModel') 

De esta manera no hay necesidad de importar MyOtherModel, así que no hay referencia circular. Django resuelve la cadena internamente, y todo funciona como se esperaba.

+0

Fantástico. Esto es exactamente lo que estaba buscando. Curiosamente, sabía que podías hacer esto, ya que lo uso en lugares donde ForeignKey hace referencia a algo que se define más adelante en el archivo, pero nunca pensé en usarlo de esta manera. ¡Muchas gracias! –

+0

Gracias, gracias. Se ha evitado mucho agravamiento. –

+1

¡Hurra! Esto debería documentarse mejor en http://docs.djangoproject.com. – slacy

1

Normalmente aboguen por la funcionalidad de división en aplicaciones más pequeñas, pero la dependencia circular entre los modelos refleja una integración tan estrecha que probablemente no está obteniendo mucho de la división y podría considerar fusionar las aplicaciones. Si eso resulta en una aplicación que se siente demasiado grande, puede haber una forma de hacer la división a lo largo de un eje diferente, lo que da como resultado un gráfico de dependencia más sensato.

3

Si usted está viendo circular modelo de dependencia que supongo que una de las tres cosas que está ocurriendo:

  • que haya definido una relación inversa a uno que ya está definido (por ejemplo, tanto por supuesto tiene muchas conferencias y la conferencia tiene un curso), que es redundante en Django
  • tiene un método modelo en la aplicación incorrecta
  • Usted está proporcionando funcionalidad en un método modelo que debería estar en un gestor de

Quizás podría mostrarnos qué está pasando en estos modelos y podemos tratar de descubrir por qué está surgiendo el problema. La dependencia del modelo circular rara vez es una indicación de que necesite combinar dos aplicaciones; es más probable (aunque no es el caso) que haya un problema con una de las definiciones de su modelo.

p.s. I am trabajando en una aplicación django similar, pero la estructura de mi aplicación es probablemente bastante diferente a la suya. Estaré encantado de darle una descripción de alto nivel si está interesado.

+0

Interesante. El problema que estoy teniendo en detalle es que un Módulo (aplicación de módulos) tiene una ClaveExtranjera a Persona (aplicación de personas), para sus estudiantes. TutorGroup en la aplicación People tiene una ForeignKey to Module: para asignar un grupo de tutores a un módulo en particular. Esto es lo que está dando como resultado el ciclo de dependencia. Puedo publicar un diagrama de los modelos también si aún no está claro. Me encantaría ver la estructura general de su proyecto; es realmente útil para ver cómo otros hacen las cosas. –

+0

Entonces, ¿la relación entre el Módulo y la Persona es múltiple (parece que debería ser)? De ser así, podría definir la relación en Persona con el parámetro related_name establecido en 'students'. Entonces module_instance.students.all() le daría el queryset que creo que está buscando. En mi caso, no tengo un modelo de persona. Tengo dos relaciones m2m de Curso a Usuario, una para estudiantes y otra para profesores. Lo mantiene súper simple. – ozan

+0

Sí, actualmente funciona con ManyToManyField, y podría pasarlo al modelo Person, pero parece menos "ordenado", tiene sentido tenerlo en el modelo Module. Tengo que tener una "Persona", ya que amplía el Usuario de Django, así puedo agregar más funcionalidades (como Descripciones de trabajo, etc.) Podría haber usado perfiles, pero esto es más simple después de algún middleware que escribí para devolver Personas en vez de Usuarios :) –

4

Esto puede no ser adecuado para su situación, pero ignorando el aspecto Django de su pregunta, la técnica general para romper dependencias circulares es dividir uno de los elementos con referencias cruzadas en un nuevo módulo.Por ejemplo:

moduleA: class1, class2 
      |  ^
      v  | 
moduleB: class3, class4 

podría llegar a ser:

moduleC: class 3 
     ^
      | 
moduleA: class 1, class 2 
        ^
        | 
moduleB:   class 4 

(O, alternativamente, usted podría tener la clase rota 2 hacia fuera en su propio módulo o ambos.!)

Por supuesto, esto no es ayuda si la clase A & B depende uno del otro. En ese caso, tal vez deberían estar en el mismo módulo, o mejor aún, tal vez alguna parte de estas clases podría dividirse en un tercer módulo, del que dependen ambas clases.

Cuestiones relacionadas