Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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).

like image 635
Monika Sulik Avatar asked Dec 28 '09 16:12

Monika Sulik


People also ask

Can Django model have two primary keys?

Do Django models support multiple-column primary keys? ¶ No. Only single-column primary keys are supported.

Can we inherit models in Django?

Models inheritance works the same way as normal Python class inheritance works, the only difference is, whether we want the parent models to have their own table in the database or not. When the parent model tables are not created as tables it just acts as a container for common fields and methods.

What is through in ManyToMany field Django?

Many-to-many relationship in a database This table is called a “through” table and each entry in this table will connect the source table (sandwich in this case) and the target table (sauce in this case). This is exactly what Django does under the hood when you use a ManyToManyField.

What is through model in Django?

The through attribute/field is the way you customize the intermediary table, the one that Django creates itself, that one is what the through field is changing.


2 Answers

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.

like image 107
Monika Sulik Avatar answered Oct 09 '22 09:10

Monika Sulik


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'))
like image 38
Benjamin Wohlwend Avatar answered Oct 09 '22 09:10

Benjamin Wohlwend