Django GenericRelated 字段条件查询引发 'GenericRelation' 对象没有属性 'field'
Django GenericRelated field conditional Query raising 'GenericRelation' object has no attribute 'field'
我有一个事件对象,除了 Notes
之外还有其他对象与 Event
有一般关系,并且没有活动字段。现在我希望能够编写一个排除所有 Events
的查询,其中 Notes
的活动字段为 False。所以我尝试执行以下操作。
queryset = Event.objects.all()
filters = (
Q(content_type__model='notes') &
Q(note__active=False)
)
queryset = queryset.exclude(filters)
这不起作用,因为它是单独的 运行 查询,并且当它尝试对没有 content_object 或不属于 Notes
类型的项目执行时,它失败并给出以下错误:
AttributeError 'GenericRelation' object has no attribute 'field'.
class Event(models.Model):
content_type = models.ForeignKey(ContentType, null=True, blank=True)
object_id = models.PositiveIntegerField(null=True, blank=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Notes(models.Model):
active = models.BooleanField(default=True)
event_log = GenericRelation(
'Event',
related_query_name='note'
)
使用 Django ORM 的常用方法是使用子查询:
Event.objects.exclude(
content_type=note_content_type,
object_id__in=Notes.objects.filter(active=False),
)
可悲的是,这个 可以 在 SQL 中用连接而不是子查询来表达,但是 ORM 并没有让那变得容易。
在某些情况下,PostgreSQL 的查询规划器可以将子查询优化为 hash semi join,因此在没有对数据。
另一种方法是使用Conditional Expression,例如
from django.db import models
queryset = Event.objects.all()
queryset = queryset.annotate(
is_inactive_note=models.Case(
models.When(
content_type__model='notes',
note__active=False,
then=models.Value(True),
),
default=models.Value(False),
output_field=models.BooleanField(),
)
).filter(is_inactive_note=False)
我有一个事件对象,除了 Notes
之外还有其他对象与 Event
有一般关系,并且没有活动字段。现在我希望能够编写一个排除所有 Events
的查询,其中 Notes
的活动字段为 False。所以我尝试执行以下操作。
queryset = Event.objects.all()
filters = (
Q(content_type__model='notes') &
Q(note__active=False)
)
queryset = queryset.exclude(filters)
这不起作用,因为它是单独的 运行 查询,并且当它尝试对没有 content_object 或不属于 Notes
类型的项目执行时,它失败并给出以下错误:
AttributeError 'GenericRelation' object has no attribute 'field'.
class Event(models.Model):
content_type = models.ForeignKey(ContentType, null=True, blank=True)
object_id = models.PositiveIntegerField(null=True, blank=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Notes(models.Model):
active = models.BooleanField(default=True)
event_log = GenericRelation(
'Event',
related_query_name='note'
)
使用 Django ORM 的常用方法是使用子查询:
Event.objects.exclude(
content_type=note_content_type,
object_id__in=Notes.objects.filter(active=False),
)
可悲的是,这个 可以 在 SQL 中用连接而不是子查询来表达,但是 ORM 并没有让那变得容易。
在某些情况下,PostgreSQL 的查询规划器可以将子查询优化为 hash semi join,因此在没有对数据。
另一种方法是使用Conditional Expression,例如
from django.db import models
queryset = Event.objects.all()
queryset = queryset.annotate(
is_inactive_note=models.Case(
models.When(
content_type__model='notes',
note__active=False,
then=models.Value(True),
),
default=models.Value(False),
output_field=models.BooleanField(),
)
).filter(is_inactive_note=False)