Django ORM:自定义一个 ListView,并向其查询集中添加更多信息
Django ORM: customize a ListView, and add more information to its queryset
我想列出某个型号(我们称之为 class A
),如下所示:
class BaseListView(ListView, MultipleObjectMixin):
http_method_names = ['get']
order_field = None
def get_paginate_by(self, queryset):
session_manager = SessionManager(self.request.session)
return session_manager.paginate_by.get()
def get_context_data(self, **kwargs):
context = super(BaseListView, self).get_context_data(**kwargs)
session_manager = SessionManager(self.request.session)
session_manager.paginate_by.set_to(context)
return context
到现在为止,这个视图只是做了需要的事情。现在我必须将它检索到的对象列表与另一个对象列表 (class B
) 进行比较。
class A
和 B
的对象都有一个主键和它们的名字。
我想检查 class A
中的任何对象是否与 class B
中的任何对象具有相同的 name
(主键)。如果 B
中有 A
的实例,我想添加某个参数或类似 is_in_B=True
.
我需要这个,以便我可以在模板中以不同的方式表示 A
的这些实例。
我该怎么做?
这是我暂时自己想出的:
class AListView(BaseListView):
model = "A"
def get_queryset(self):
queryset = super(AListView, self). get_query_set()
all_objects_A = A.objects.all()
all_objects_B = B.objects.all()
# modify queryset to indicate which instances of A are present in B
# No idea how to do this
return queryset
我不太确定这是一种合适的方法。
此外,我应该如何修改我的 class 返回的 queryset
,以便我可以指出 class A
的哪些实例共享相同的 name
class B
?
的实例数
你可以annotate your queryset with a conditional expression实现这个:
from django.db.models import Case, When, Value
def get_queryset(self):
# This gives you the queryset of A objects
queryset = super(AListView, self).get_queryset()
# List of primary keys of B objects
all_objects_B = B.objects.all().values_list('pk',flat=True)
# modify queryset to indicate which instances of A are present in B
return queryset.annotate(
is_in_b=Case(When(pk__in=all_objects_B, then=Value(True)),
default=Value(False))
)
)
您的查询集对象现在将有一个 is_in_b
属性。
如果您的 B 对象列表很小,这会很好地工作。如果它很大那么我不确定它是否非常有效,您可能需要进一步开发它以查看是否可以直接在数据库中完成检查(是 B 中的 A)(可能需要原始 SQL) .
我想列出某个型号(我们称之为 class A
),如下所示:
class BaseListView(ListView, MultipleObjectMixin):
http_method_names = ['get']
order_field = None
def get_paginate_by(self, queryset):
session_manager = SessionManager(self.request.session)
return session_manager.paginate_by.get()
def get_context_data(self, **kwargs):
context = super(BaseListView, self).get_context_data(**kwargs)
session_manager = SessionManager(self.request.session)
session_manager.paginate_by.set_to(context)
return context
到现在为止,这个视图只是做了需要的事情。现在我必须将它检索到的对象列表与另一个对象列表 (class B
) 进行比较。
class A
和 B
的对象都有一个主键和它们的名字。
我想检查 class A
中的任何对象是否与 class B
中的任何对象具有相同的 name
(主键)。如果 B
中有 A
的实例,我想添加某个参数或类似 is_in_B=True
.
我需要这个,以便我可以在模板中以不同的方式表示 A
的这些实例。
我该怎么做?
这是我暂时自己想出的:
class AListView(BaseListView):
model = "A"
def get_queryset(self):
queryset = super(AListView, self). get_query_set()
all_objects_A = A.objects.all()
all_objects_B = B.objects.all()
# modify queryset to indicate which instances of A are present in B
# No idea how to do this
return queryset
我不太确定这是一种合适的方法。
此外,我应该如何修改我的 class 返回的 queryset
,以便我可以指出 class A
的哪些实例共享相同的 name
class B
?
你可以annotate your queryset with a conditional expression实现这个:
from django.db.models import Case, When, Value
def get_queryset(self):
# This gives you the queryset of A objects
queryset = super(AListView, self).get_queryset()
# List of primary keys of B objects
all_objects_B = B.objects.all().values_list('pk',flat=True)
# modify queryset to indicate which instances of A are present in B
return queryset.annotate(
is_in_b=Case(When(pk__in=all_objects_B, then=Value(True)),
default=Value(False))
)
)
您的查询集对象现在将有一个 is_in_b
属性。
如果您的 B 对象列表很小,这会很好地工作。如果它很大那么我不确定它是否非常有效,您可能需要进一步开发它以查看是否可以直接在数据库中完成检查(是 B 中的 A)(可能需要原始 SQL) .