dev-jim
dev-jim

Reputation: 2524

Django - queryset for multiple models that related with foreignkey

I have models.py like this:

class Post(models.Model):
    name = models.CharField(max_length=100,blank=True)
    author = models.ForeignKey(User, null=True, blank=True)
    ...

class Categories(models.Model):
   category = models.CharField(max_length=200)
   post_id = models.ForeignKey(Post)

class Tags(models.Model):
  tag = = models.CharField(max_length=200)
  tag_id = models.ForeignKey(Post)  

How do I get the all the related objects if given the author id. eg. In the view.py

def AllPost(request, userid):
    posts = Post.objects.filter(author=userid)
    for post in Posts:
         category = Categories.filter(post_id = post.id)
         tag = Tags.filter(post_id = post.id)

The problem of the function above will causes extra query for each of the post. Is there any way to call all the objects in single query??

Upvotes: 1

Views: 4143

Answers (2)

ruddra
ruddra

Reputation: 52028

How about like this:

Categories= Category.objects.filter(tag_id__author=userid) #assuming userid is an User object like for example: request.User
Tags= Tags.objects.filter(post_id__auther=userid)

if you want to get both category and tags from Post in single query, then you will get ValuesQuerySet from following query:

data= Post.objects.filter(auther=userid).values_list('category', 'tags') #or .values_list('category__category', 'tags__tag') 

Upvotes: 1

laffuste
laffuste

Reputation: 17115

For django >= 1.4, use prefecth_related.

class Post(models.Model):
    name = models.CharField(max_length=100,blank=True)
    author = models.ForeignKey(User, null=True, blank=True)
    ...

class Categories()models.Model:
   category = models.CharField(max_length=200)
   post = models.ForeignKey(Post, related_name='categories')

 

def get_all_posts(request, user_id):
    posts = Post.objects.filter(author=user_id).prefetch_related('categories')
    for post in posts:
         categories = post.categories

(Note: some code errors fixed.)

For django < 1.4, you can use django_prefetch plugin.

Upvotes: 1

Related Questions