Skip to main content
 首页 » 编程设计

python之Django ORM : customize a ListView, 并向其查询集添加更多信息

2025年04月02日39dflying

我想列出某个型号(我们称之为 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 

到现在为止,这个 View 只是做了需要的事情。现在我必须将它检索到的对象列表与另一个对象列表 (class B) 进行比较。

类的对象A和 B两者都有一个带有他们名字的主键。

我想检查 class A 中是否有任何对象具有相同的name (主键)作为 class B 中的任何对象.如果有一个 A 的实例在B我想添加某个参数或类似 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 

我不太确定这是一种合适的方法。

此外,我应该如何修改 queryset由我的类(class)返回,以便我可以指出 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)。