2009-05-21 13 views
21

Io sono nel mezzo di sviluppo di un'applicazione Django, che ha modelli molto complicati (Modelle in un'università - corsi, moduli, lezioni, studenti, ecc)Django App Dipendenza Ciclo

ho separato il progetto in applicazioni , per rendere il tutto più organizzato (le app sono corsi, scuole, persone, moduli e tempistiche). Sto avendo un problema per cui un modello in una app può dipendere da un modello in un altro - quindi devo importarlo. La seconda app a sua volta dipende da un modello nel primo, quindi c'è un ciclo e Python genera un errore.

Come le persone si occupano di questo? Capisco che le app dovrebbero essere relativamente "indipendenti", ma in un sistema come questo non ha senso, ad esempio, usare ContentTypes per collegare gli studenti a un modulo.

Qualcuno ha un progetto simile che potrebbe commentare questo caso?

+0

Lo scenario non sembra quello per cui sono state create le app. L'idea delle app è la riusabilità (insieme alla confezione separata, alla distribuzione e al controllo delle versioni). Potresti risparmiare qualche problema non forzando le aree tematiche in app separate. –

risposta

52

Se la propria dipendenza è con chiavi esterne che fanno riferimento a modelli in altre applicazioni, è necessario che non sia per importare l'altro modello. È possibile utilizzare una stringa nella definizione ForeignKey:

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

In questo modo non c'è bisogno di importare MyOtherModel, in modo che nessun riferimento circolare. Django risolve la stringa internamente e funziona come previsto.

+0

Fantastico. Questo e 'esattamente quello che stavo cercando. Stranamente, sapevo che si poteva fare questo - come lo uso in luoghi in cui ForeignKey fa riferimento a qualcosa che viene definito più avanti nel file, ma non ho mai pensato di usarlo in questo modo. Grazie mille! –

+0

Grazie grazie. Gran parte dell'aggravamento è stata evitata. –

+1

Urrà! Questo dovrebbe essere meglio documentato su http://docs.djopoproject.com – slacy

1

Normalmente sostengo la suddivisione delle funzionalità in app più piccole, ma una dipendenza circolare tra i modelli riflette un'integrazione così stretta che probabilmente non stai ottenendo molto dalla divisione e potresti semplicemente considerare di unire le app. Se ciò si traduce in un'app che sembra troppo grande, potrebbe esserci un modo per rendere la divisione lungo un asse diverso, risultante in un grafico di dipendenza più sensato.

3

Se stai vedendo circolare dipendenza modello Sto indovinando che una delle tre cose sta accadendo:

  • Hai definito una relazione inversa a quella che è già definito (per esempio sia ovviamente ha molte lezioni e conferenza ha un corso), che è ridondante in Django
  • si dispone di un metodo di modello nella applicazione sbagliata
  • si sta fornendo funzionalità in un metodo modello che dovrebbe essere in un manager

Forse potresti mostrarci cosa sta succedendo in questi modelli e possiamo provare a capire perché il problema sta sorgendo. Raramente la dipendenza del modello circolare indica che è necessario combinare due app: è più probabile (anche se non è proprio così) che c'è un problema con una delle definizioni del modello.

p.s. I am funziona su un'applicazione django simile, ma la mia struttura dell'app è probabilmente molto diversa dalla tua. Sarei felice di darti una descrizione di alto livello di questo se sei interessato.

+0

Interessante. Il problema che sto avendo in dettaglio, è che un Modulo (app moduli) ha una ForeignKey per Persona (app per le persone), per i suoi studenti. TutorGroup nell'app delle persone ha quindi una ForeignKey per il modulo - per assegnare un gruppo di tutor a un particolare modulo. Questo è ciò che risulta nel ciclo delle dipendenze. Posso pubblicare un diagramma dei modelli anche se non è ancora chiaro. Mi piacerebbe vedere la struttura generale del tuo progetto: è davvero utile vedere come gli altri fanno cose. –

+0

Quindi la relazione tra Modulo e Persona molti-a-molti (sembra che dovrebbe essere)? In tal caso, è possibile definire la relazione in Persona con il parametro related_name impostato su "studenti". Quindi module_instance.students.all() ti darebbe il queryset che penso tu stia cercando. Nel mio caso, non ho un modello Persona. Ho due relazioni m2m da Corso a Utente, una per studenti e un'altra per insegnanti. Mantiene il tutto super semplice – ozan

+0

Sì, al momento funziona con ManyToManyField - e potrei spostarlo sul modello Persona - ma sembra meno "pulito" - ha senso averlo sul modello Module. Devo avere una "Persona" mentre estende l'Utente di Django, quindi posso aggiungere più funzionalità (come Descrizioni di lavoro ecc.) Potrei avere profili di utilizzo ma questo è più semplice dopo un middleware che ho scritto per restituire People invece di Users :) –

4

Questo può non essere molto adatta alla situazione, ma ignorando l'aspetto Django alla domanda, la tecnica generale per rompere le dipendenze circolari è di rompere uno degli elementi riferimenti incrociati in un nuovo modulo.Per esempio:

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

potrebbe diventare:

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

(O, in alternativa, si potrebbe avere classe rotto 2 in un proprio modulo o entrambe le cose.!)

Naturalmente, questo non è un aiuto se la classe A & B dipende l'una dall'altra. In tal caso, forse dovrebbero essere nello stesso modulo, o meglio ancora, forse una parte di queste classi potrebbe essere scomposta in un terzo modulo, dal quale dipendono entrambe le classi.