Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
588 views
in Technique[技术] by (71.8m points)

python - How to get filtered queryset in django admin?

I have many different filters in Django admin:

class OrderAdmin(admin.ModelAdmin):
    ...
    list_filter = ('field_1', 'field_2', 'field_3', ... , 'field_N')
    ...

I need to get filtered queryset in my overridden method changelist_view before parent changelist_view is called:

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)
    ...

if I calling get_queryset before super in changelist_view it returns queryset without filters.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

New version of Django admin use custom objects for ChangeList view with custom get_queryset method.

As you can see in Django source:

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))
    ...

You must override self.get_changelist(request) and return your custom ChangeList with overridden 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

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']

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...