[Django]-Django Relation between two models

4👍

Breaking cyclic imports

You defined a cyclic import: one module first has to import the other module, but the other module fist has to implement that module, so you defined a cycle.

In Django, one does not per se has to use a class reference to make ForeignKeys, one can use strings that refer to the correct model. In that case the Django framework, will later resolve these.

So we can break the cycle, for example with:

# sections/models.py

# no import from articles

# Create your models here.
class Section(models.Model): 
    #associations
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    # we use a string literal
    article = models.ForeignKey('articles.Article', on_delete=models.CASCADE)

and then in the articles/models.py:

# articles/models.py

from sections.models import Section
User = settings.AUTH_USER_MODEL

# Create your models here.
class Article(models.Model):
    owner = models.ForeignKey(User, null=False)
    sections = models.ManyToManyField(Section)

So here we no longer import articles/models.py in the sections/models.py, and thus we break the cyclic import.

Note that you need to specify an on_delete for a ForeignKey, for example models.CASCADE.

Django’s reverse relations

For this specific application however, it seems that you make a double relation between Section and Article, that basically is one relation, you should not do that, Django automatically writes the reverse relation, what you probably want to do, is give it a proper name, for example:

# sections/models.py

# no import from articles

# Create your models here.
class Section(models.Model): 
    #associations
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    # we use a string literal
    article = models.ForeignKey(
        'articles.Article',
        on_delete=models.CASCADE,
        related_name='sections'
    )

and for articles/models.py:

# articles/models.py

User = settings.AUTH_USER_MODEL

# Create your models here.
class Article(models.Model):
    owner = models.ForeignKey(User, null=False)
    # no relation to section

Here we can obtain all Sections that relate to some_article with some_article.sections.all().

Leave a comment