kemumaki
kemumaki

Reputation: 53

How to setup many to many one to many and many to one relationship in django

From the last seven days I am trying to build a blog using django and I figured out the model for my blog as follows

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    created_at = models.DateTimeField('created date', auto_now_add=True, auto_now=False)
    updated_at = models.DateTimeField('updated date', auto_now_add=False, auto_now=True)

    def __str__(self):
        return self.title


class Author(models.Model):
    name = models.CharField(max_length=150)
    email = models.EmailField(blank=True)
    bio = models.TextField()
    #This line define many author can have a post
    #but I want manypost can only have single author.
    #in my view to accomplish this i need to define author in Post class
    #on defining author=ForeignKey(Author) in post, It throws  an error Author is not defined
    post = models.ForeignKey(Post) 

    def __str__(self):
        return self.author

class Category(models.Model):
    cat_name = models.CharField(max_length=200)
    post = models.ManyToManyField(Post)

    def __str__(self):
        return self.cat_name

The thing that I am so much confused is the relation between the Post, Categories, Author and Tag.

Relation What I wanted to set is

  1. author can have many posts, A post can have only single author
  2. categories can have many posts, A post can have many categories
  3. a tag can have many posts a post can have many tags

But the models that I am created above is not working as I expected(I am so confused).

when I put the author field in Post Class, so that i would be a relation like, an author can have many posts, but I got the error Author is not defined.(as I know the interpreter run code from top to bottom). How do I accomplish

Upvotes: 0

Views: 158

Answers (3)

xyres
xyres

Reputation: 21734

  1. author can have many posts, A post can have only single author

Post model should have a ForeignKey pointing to Author.

class Post(...):
    author = models.ForeignKey('Author')
  1. categories can have many posts, A post can have many categories

Post model should have a ManyToManyField pointing to Category.

class Post(...):
    category = models.ManyToManyField('Category')
  1. a tag can have many posts a post can have many tags

Same as number 2.

Upvotes: 0

Dean Christian Armada
Dean Christian Armada

Reputation: 7364

Try model structure syntax:

class Author(models.Model):
    name = models.CharField(max_length=150)
    email = models.EmailField(blank=True)
    bio = models.TextField()

    def __str__(self):
        return self.author

class Post(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=200)
    body = models.TextField()
    created_at = models.DateTimeField('created date', auto_now_add=True, auto_now=False)
    updated_at = models.DateTimeField('updated date', auto_now_add=False, auto_now=True)

    def __str__(self):
        return self.title

class Category(models.Model):
    cat_name = models.CharField(max_length=200)
    post = models.ManyToManyField(Post)

    def __str__(self):
        return self.cat_name

class Tag(models.Model):
    tag_name = models.CharField(max_length=200)
    post = models.ManyToManyField(Post)

    def __str__(self):
        return self.tag_name

This will solve your three requirements:
1.) Author can have many posts because I set the Post Model into one-to-many field
2.) Categories can have many posts vice versa (This is already set according to your code)
3.) Tag can have many posts vice versa (Very similar to your already made Category Model where I made the field many-to-many between the two)

The reason why you got an error is because you made your author to post relation to many-to-one (many authors in one post) according to your model structure

Now to test it simply migrate all these changes and quickly test it in your admin page

Upvotes: 0

Ali Nikneshan
Ali Nikneshan

Reputation: 3502

You have two options:

  1. Change Author and Post position, thus Page can see Post definition.
  2. Use Lazy call as: author= models.ForeignKey("Author")

In this way, Django will wait until all models load then resolve the dependencies.

Upvotes: 1

Related Questions