如何在django admin中获取过滤的查询集?

rea*_*act 7 python django

我在Django管理员中有许多不同的过滤器:

class OrderAdmin(admin.ModelAdmin):
    ...
    list_filter = ('field_1', 'field_2', 'field_3', ... , 'field_N')
    ...
Run Code Online (Sandbox Code Playgroud)

在调用changelist_viewparent之前,我需要在我的重写方法中获取过滤的查询集changelist_view:

class OrderAdmin(admin.ModelAdmin):
    ...
    def changelist_view(self, request, extra_content=None):
        # here i need filtered queryset and I don`t know 
        # which filters have been applied
        return super().changelist_view(request, extra_context)
    ...
Run Code Online (Sandbox Code Playgroud)

如果我打电话get_queryset之前,superchangelist_view它返回的查询集不带过滤器.

pah*_*haz 9

新版本的Django管理员使用自定义get_queryset方法为ChangeList视图使用自定义对象.

正如你在Django中看到的那样:

def changelist_view(self, request, extra_context=None):
    ...
    ChangeList = self.get_changelist(request)

    cl = ChangeList(request, self.model, list_display,
        list_display_links, list_filter, self.date_hierarchy,
        search_fields, list_select_related, self.list_per_page,
            self.list_max_show_all, self.list_editable, self)

    # Actions with no confirmation
    if (actions and request.method == 'POST' and
            'index' in request.POST and '_save' not in request.POST):
        if selected:
            response = self.response_action(request, queryset=cl.get_queryset(request))
    ...
Run Code Online (Sandbox Code Playgroud)

您必须覆盖self.get_changelist(request)并返回自定义的ChangeList并重写get_queryset.

ModelAdmin.get_changelist:

def get_changelist(self, request, **kwargs):
    """
    Returns the ChangeList class for use on the changelist page.
    """
    return MyChangeList  # PUT YOU OWERRIDEN CHANGE LIST HERE
Run Code Online (Sandbox Code Playgroud)

MyChangeList:

from django.contrib.admin.views.main import ChangeList

class MyChangeList(ChangeList):
    def get_queryset(...):
        # if you want change get_queryset logic or add new filters
        ...
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # if you want add some context variable which can be accessed by 
        # {{ cl.some_context_varibale }} variable
        self.some_context_varibale = self.queryset.aggregate(Avg('price'))['price__avg']
Run Code Online (Sandbox Code Playgroud)


emy*_*ler 5

您可以篡改原始调用返回的响应changelist_view。例如,要在管理员实例过滤后使用查询集 添加一些额外的模板上下文数据:ChangeList

def changelist_view(self, request, extra_context=None):
    # Obtain the original response from Django
    response = super().changelist_view(request, extra_context)

    # Extract the final queryset from the ChangeList object
    change_list = response.context_data['cl']
    queryset = change_list.queryset

    # Do stuff with the queryset
    stats = self.get_stats(queryset)

    # Inject a new key in the template context data
    response.context_data['stats'] = stats

    return response
Run Code Online (Sandbox Code Playgroud)