我有一个带标签的简单博客应用。
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
例如,在我的数据库中有两个帖子。在帖子A和帖子B中有标签' a'''' c'和' d'' e',' f'分别。为了减少对数据库的查询,我尝试使用extra()方法。
condition = 'blog_post.id = blog_tag.post_id'
p = Post.objects.all().extra(select={'t':'blog_tag.slug'},tables=["blog_tag"],where=[condition])
结果:
[<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'
如何获得每个帖子的副本,其中所有标签都列在一个attr中,如下所示:
p =[<Post: A>, <Post: B>]
for post in p: print post.t
['a','b','c']
['d','e','f']
答案 0 :(得分:1)
根本不会使用extra
。而是使用prefetch_related
在两个查询中获取帖子及其所有关联的标签:
p = Post.objects.all().prefetch_related('tag')
答案 1 :(得分:1)
我不确定您是否要在Tag模型中使用ForeignKey。在Django中,ForeignKey是多对一的,而你可能更喜欢many-to-many关系(意思是:一个帖子可以有多个标签,一个标签可以引用多个帖子)。
为了解决性能问题,我正在使用select_related
:
返回一个“跟随”外键关系的QuerySet, 在执行查询时选择其他相关对象数据。 这是一个性能助推器,导致单一更复杂 查询但意味着以后使用外键关系不需要 数据库查询。
答案 2 :(得分:0)
你试过django-taggit吗?它可能会让你的生活更轻松。只需将其插入即可。该文档包含一些您可能想要做的示例查询。