سؤال

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']
هل كانت مفيدة؟

المحلول

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')

نصائح أخرى

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.

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top