Django Queryset:按相关项目管理器过滤
Django Queryset: filtering by related item manager
我有包含多个内容块的页面模型。
class Page(models.Model):
...
class Block(models.Model):
page = models.ForeignKey(Page)
...
Block
有一些其他属性决定它是否被认为是 "active" (一对布尔值和一个日期时间字段)。我有一个 Block
模型的管理器,这样我就可以获得活动块列表
Block.objects.active()
Page.objects.first().block_set.active()
我希望能够将查询集写入 return 只有 Page
个具有活动块的对象。我想使用现有的 Block
活动管理器来执行此操作,因此我只定义一次 "active" 块的内容(DRY)。 IE 类似于:
Page.objects.annotate(count=Count('block__active')).filter(count__gt=0)
显然这不起作用,因为 active
不是 Block
的 属性。有什么方法可以使用现有的 Block
管理器来实现这一点?
据我所知,没有办法使用单个 queryset
来实现它,因为您想使用您的经理中可用的 active()
。但是您可以通过将 related name 添加到 Block
模型中的 Page
来实现结果:
class Block(models.Model):
page = models.ForeignKey(Page, related_name='related_block')
...
现在您的代码应该是:
active_blocks = Block.objects.active() # Queryset with all active blocks
# Queryset of Pages with Block in 'active_blocks'
active_pages = Page.objects.filter(related_block__in=active_blocks)
现在在此 QuerySet 上,您可以执行 annonate
或任何您希望在 Page
的 QuerySet 上允许的操作。
为什么不直接在模型上添加一个布尔字段,例如 is_active
,然后在 save()
或 set_active()
上更新它?然后您就可以通过该字段查询您的模型。
我有包含多个内容块的页面模型。
class Page(models.Model):
...
class Block(models.Model):
page = models.ForeignKey(Page)
...
Block
有一些其他属性决定它是否被认为是 "active" (一对布尔值和一个日期时间字段)。我有一个 Block
模型的管理器,这样我就可以获得活动块列表
Block.objects.active()
Page.objects.first().block_set.active()
我希望能够将查询集写入 return 只有 Page
个具有活动块的对象。我想使用现有的 Block
活动管理器来执行此操作,因此我只定义一次 "active" 块的内容(DRY)。 IE 类似于:
Page.objects.annotate(count=Count('block__active')).filter(count__gt=0)
显然这不起作用,因为 active
不是 Block
的 属性。有什么方法可以使用现有的 Block
管理器来实现这一点?
据我所知,没有办法使用单个 queryset
来实现它,因为您想使用您的经理中可用的 active()
。但是您可以通过将 related name 添加到 Block
模型中的 Page
来实现结果:
class Block(models.Model):
page = models.ForeignKey(Page, related_name='related_block')
...
现在您的代码应该是:
active_blocks = Block.objects.active() # Queryset with all active blocks
# Queryset of Pages with Block in 'active_blocks'
active_pages = Page.objects.filter(related_block__in=active_blocks)
现在在此 QuerySet 上,您可以执行 annonate
或任何您希望在 Page
的 QuerySet 上允许的操作。
为什么不直接在模型上添加一个布尔字段,例如 is_active
,然后在 save()
或 set_active()
上更新它?然后您就可以通过该字段查询您的模型。