binny
binny

Reputation: 729

NameError: name *model* is not defined; ManyToManyField/ForeignKey

Here is a relationship I'm aiming for in terms of a User, Question, Bookmark relationship; Bookmark being an intermediary table:

The keyword here being bookmark(ed), I have created a Bookmark model to show this relationship. However there's a problem of trying to make migrations due to a NameError being raised. Depending where they are defined in the script it's raising either:

NameError: name 'Question' is not defined

NameError: name 'Bookmark' is not defined

How can I get past this error in order to push the Bookmark into the migrations directory with its ForeignKey references?

class Question(models.Model):
    title = models.CharField(unique=True, max_length=40)
    body = models.TextField()
    created = models.DateField(auto_now_add=True)
    likes = models.IntegerField(default=0)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True
    )
    views = models.ManyToManyField(
        View,
        related_name="+"
    )
    tags = models.ManyToManyField(
        Tag,
        related_name="questions"
    )
    bookmarks = models.ManyToManyField(
        Bookmark,
        related_name="+",
    )

    def __str__(self):
        return self.title


class Bookmark(models.Model):
    question = models.ForeignKey(
        Question, on_delete=models.CASCADE,
        related_name="+"
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
        related_name="bookmarks"
    )

Upvotes: 0

Views: 624

Answers (1)

Jasmijn
Jasmijn

Reputation: 10452

Pass the related model as a string to the field constructor:

    bookmarks = models.ManyToManyField(
        'Bookmark',
        related_name="+",
    )

Django looks up the model class only when it's necessary, so it can support recursive foreign key shenanigans.

From the Django documentation:

If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself.

Upvotes: 1

Related Questions