Django: Is there a way to have the "through" model in a ManyToManyField in a different app to the model containing the ManyToManyField?
Asked Answered
A

2

8

Lets say I have two django apps:

  • competitions - which will handle competition data
  • entries - which will handle functionality relating to entering competitors into competitions

In the competitions app I have a model which represents a section of a competition:

class Division(models.Model):
    competition = models.ForeignKey(Competition)
    discipline = models.CharField(max_length=1, choices=DISCIPLINE_CHOICES)
    age_group = models.ForeignKey(AgeGroup)
    participants = models.ManyToManyField(Competitor, through='Entry')

I want to put the Entry model in the entries app:

class Entry(models.Model):
    division = models.ForeignKey('Division')
    competitor = models.ForeignKey(Competitor)
    withdrawn = models.BooleanField(default=False)

How do I solve the from ... import ... statements, so that they work? When I put in import statements such as from entries.models import Entry I get the models from these apps ignored by syncdb (because the imports are circular) or when I remove one or both of them I get validation errors:

Error: One or more models did not validate: entries.entry: 'division' has a relation with model Division, which has either not been installed or is abstract. competitions.division: 'participants' specifies an m2m relation through model Entry, which has not been installed

I understand why this happens, but I have no idea how to change this, so that it works (without resorting to moving the Entry model into the competitions app, which I really don't want to do).

Azygous answered 28/12, 2009 at 16:50 Comment(1)
can you post the Competitor class?Institutionalism
A
16

It seems like I've found an answer, which works more consistently :)

The Django documentation on the ForeignKey class says:

To refer to models defined in another application, you can explicitly specify a model with the full application label. For example, if the Manufacturer model above is defined in another application called production, you'd need to use:

class Car(models.Model):
    manufacturer = models.ForeignKey('production.Manufacturer')

This sort of reference can be useful when resolving circular import dependencies between two applications.

Azygous answered 4/1, 2010 at 15:4 Comment(0)
S
5

sometimes, django.db.models.get_model helps to work around circular imports. In your example, try to import Entry normally and chage the division FK definition in Entry to this:

from django.db.models import get_model

class Entry(models.Model):
    division = models.ForeignKey(get_model('competitions', 'Division'))
Sequin answered 28/12, 2009 at 17:1 Comment(2)
From what I can see this doesn't always work... I guess it depends on the order in which django loads the apps or something like that. Still - very useful tip, thanks :)Azygous
get_model() might return None.Darfur

© 2022 - 2024 — McMap. All rights reserved.