Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Relation between two models

Tags:

django

I am very new to Django.

Can you please give a boilerplate of models how to relate two models between each other.

--Below is Section model

from articles.models import Article
# Create your models here.
class Section(models.Model): 
    #associations
    user    = models.ForeignKey(settings.AUTH_USER_MODEL)
    article = models.ForeignKey(Article) #Article

--Below is Article model

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 )

However. I got the below error: ValueError: Cannot create form field for 'article' yet, because its related model 'articles.models' has not been loaded yet

Thanks All

B

like image 459
yangbin990 Avatar asked Mar 04 '26 03:03

yangbin990


1 Answers

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

like image 71
Willem Van Onsem Avatar answered Mar 07 '26 05:03

Willem Van Onsem