Django:使用另一个表的结果过滤对象?

时间:2010-11-26 03:32:28

标签: django django-views

我对如何在Django中做到这一点感到很遗憾,希望你能提供帮助。

我有一个我按类型过滤的画廊表:

public_galleries = models.Gallery.objects.filter(type = 2).filter(root_gallery__isnull = True)

但我还想查看特定用户的UserGallery表中是否存在该库。我有这个用户列表:

user_galleries = models.UserGallery.objects.select_related().filter(clientuser=request.user.id).filter(gallery__root_gallery__isnull = True)

注意**刚刚开始将Django用于实际项目,因此对这两种语句的任何改进都表示赞赏。

编辑 - 模特:

class Gallery(models.Model):
    """Gallery model"""
    name = models.CharField(u"Gallery name", max_length=120)
    type = models.IntegerField(default=0, choices=TYPE_CHOICES)
    root_gallery = models.ForeignKey("self", blank=True, null=True)
    """ Other Fields"""

class UserGallery(models.Model):
    """Model to link Gallery and ClientUser"""
    gallery = models.ForeignKey(Gallery)
    clientuser = models.ForeignKey(ClientUser)
    owner = models.BooleanField(default=False)

3 个答案:

答案 0 :(得分:5)

Gallery.objects.filter(type = 2).filter(root_gallery__isnull = True).exclude(id__in = [x.id for x in request.user.usergallery_set()])

应该这样做。

答案 1 :(得分:3)

这个答案对于中等大量的user_galleries都不起作用,因为你每次都将它们加载到一个列表中。

更好的方法是使用QuerySet的extra()方法,该方法允许您在SQL中为WHERE子句指定其他条件。

来自Django文档:

  

您可以使用where来定义显式SQL WHERE子句 - 可能用于执行非显式连接。您可以使用表格手动将表添加到SQL FROM子句。

在你的情况下像

private_galleries = Gallery.objects.filter(type=1, root_gallery__isnull=True) \
    .extra(where=['''
        yourapp_gallery.id NOT IN (SELECT id FROM 
            ...long query used to generate user_galleries...  )
    '''])

会奏效。不幸的是,这意味着将生成user_galleries的查询转录为SQL,因此您需要确定DRY /可维护性权衡是否值得节省在每个查询中将该列表加载到内存中的开销。我怀疑除了一小部分user_galleries之外还有其他任何东西。

请注意,where= arg采用字符串的列表

来自邮件列表here的更多信息。

答案 2 :(得分:0)

我要感谢Mayuresh的帮助

我不知道为什么会出现这个错误,但我找到了解决方案:

private_galleries = models.Gallery.objects.filter(type = 1).filter(root_gallery__isnull = True).exclude(id__in = [x.gallery.id for x in user_galleries])