Reputation: 147
I have a simple blog app with tags.
class AbstractDate(models.Model):
created = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True
class AbstractTitleData(AbstractDate):
title = models.CharField(max_length=200)
class Meta:
abstract = True
class Post(AbstractTitleData):
body = models.TextField()
views = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
picture = models.ImageField(upload_to='profile_images', blank=True)
class Meta:
ordering = ["-created"]
def __unicode__(self):
return self.title
class Tag(models.Model):
slug = models.SlugField(max_length=15)
post = models.ForeignKey(Post, related_name="tags")
def __unicode__(self):
return self.slug
For example, in my db have two posts. There are post A and post B with tags 'a', 'b', 'c', and 'd', 'e', 'f' respectively. To reduce queries to the database, I'm trying to use extra() method.
condition = 'blog_post.id = blog_tag.post_id'
p = Post.objects.all().extra(select={'t':'blog_tag.slug'},tables=["blog_tag"],where=[condition])
Result:
[<Post: A>, <Post: A>, <Post: A>, <Post: B>, <Post: B>, <Post: B>]
for post in p: print post.t
'a'
'b'
'c'
'd'
'e'
'f'
How can I get a copy of each post with all their tags listed in one attr, like so:
p =[<Post: A>, <Post: B>]
for post in p: print post.t
['a','b','c']
['d','e','f']
Upvotes: 0
Views: 179
Reputation: 500
Have you tried django-taggit? It may make your life easier. Just plug it in and go. The documentation has some example queries for what you may want to do.
Upvotes: 0
Reputation: 599610
You wouldn't use extra
for that at all. Instead, use prefetch_related
to fetch the posts and all their associated tags in two queries:
p = Post.objects.all().prefetch_related('tag')
Upvotes: 1
Reputation: 7202
I'm not sure that you want to use a ForeignKey in your Tag model. In Django, a ForeignKey is a many-to-one, while you'd probably prefer a many-to-many relationship (meaning: one post can have multiple tags and one tag can refer to multiple posts).
To deal with performance issues, I'm using select_related
:
Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query. This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.
Upvotes: 1