Django 관리자의 기본 필터


94

'전체'에서 기본 필터 선택을 어떻게 변경할 수 있습니까? , 및 이라는 status세 가지 값 이있는라는 필드 가 있습니다. Django 관리자에서 사용할 때 필터는 기본적으로 '모두'로 설정되지만 기본적으로 보류로 설정하고 싶습니다.activatependingrejectedlist_filter

답변:


102

이를 달성 하고 사이드 바에 사용 가능한 '모두'링크 (즉, 보류 중을 표시하지 않고 모두 표시하는 링크)를 가지려면 django.contrib.admin.filters.SimpleListFilter기본적으로 '보류 중'을 상속 하고 필터링 하는 사용자 지정 목록 필터를 만들어야합니다 . 다음 라인을 따라 작동해야합니다.

from datetime import date

from django.utils.translation import ugettext_lazy as _
from django.contrib.admin import SimpleListFilter

class StatusFilter(SimpleListFilter):
    title = _('Status')

    parameter_name = 'status'

    def lookups(self, request, model_admin):
        return (
            (None, _('Pending')),
            ('activate', _('Activate')),
            ('rejected', _('Rejected')),
            ('all', _('All')),
        )

    def choices(self, cl):
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == lookup,
                'query_string': cl.get_query_string({
                    self.parameter_name: lookup,
                }, []),
                'display': title,
            }

    def queryset(self, request, queryset):
        if self.value() in ('activate', 'rejected'):
            return queryset.filter(status=self.value())    
        elif self.value() == None:
            return queryset.filter(status='pending')


class Admin(admin.ModelAdmin): 
    list_filter = [StatusFilter] 

편집 : Django 1.4 필요 (Simon에게 감사)


3
이것은 모든 것 중에서 가장 깨끗한 솔루션이지만, 가장 적은 upvotes를 가지고 있습니다 ...하지만 Django 1.4가 필요하지만 지금은 주어져야합니다.
Simon

@Greg 관리자 페이지 에서 필터 및 필터 탭 의 기능을 어떻게 완전히 제거 합니까?


2
이 솔루션에는 작은 단점이 있습니다. 필터가 비어 있으면 (실제로 '보류 중'필터 사용) Django 1.8은 전체 결과 수를 잘못 결정하고 show_full_result_count 가 True (기본값) 이면 결과 수를 표시하지 않습니다 . –
Alexander Fedotov 2015 년

choices솔루션 의 메서드 를 재정의하지 못하면 선택 목록 맨 위에 자체 All 옵션을 계속 추가 합니다.
리처드

47
class MyModelAdmin(admin.ModelAdmin):   

    def changelist_view(self, request, extra_context=None):

        if not request.GET.has_key('decommissioned__exact'):

            q = request.GET.copy()
            q['decommissioned__exact'] = 'N'
            request.GET = q
            request.META['QUERY_STRING'] = request.GET.urlencode()
        return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context)

18
이 솔루션에는 "모두"선택이 여전히 UI에 표시되지만 선택하면 여전히 기본 필터링이 적용된다는 단점이 있습니다.
akaihola

나는 같은 질문이 있지만 리플레이를 이해할 수 있습니다. 죄송합니다. Django와 함께 새로운 메신저입니다.하지만 아마도 이것은 blog.dougalmatthews.com/2008/10/에서
Asinox

이것은 좋지만 내 필터가 그것을 선택하고 표시 할 수 있도록 URL에서 get 매개 변수를 확인해야했습니다. 곧 내 솔루션을 게시합니다.
radtek 2014 년

설명이 없습니다. 코드를 게시하는 것만으로는 모든 사람에게 도움이되지 않을 수 있습니다. 게다가 작동하지 않고 약간의 컨텍스트 없이는 이유를 찾기가 어렵습니다.
EvilSmurf

19

와 비교하여 "모든"의 선택을 할 수 있도록 수정 위의 ha22109의 답변을 툭 HTTP_REFERER하고 PATH_INFO.

class MyModelAdmin(admin.ModelAdmin):

    def changelist_view(self, request, extra_context=None):

        test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO'])

        if test[-1] and not test[-1].startswith('?'):
            if not request.GET.has_key('decommissioned__exact'):

                q = request.GET.copy()
                q['decommissioned__exact'] = 'N'
                request.GET = q
                request.META['QUERY_STRING'] = request.GET.urlencode()
        return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context)

3
HTTP_REFERER가 항상 존재하는 것은 아니기 때문에 이것은 나를 위해 깨졌습니다. 나는 'referer = request.META.get ('HTTP_REFERER ',' '); test = referer.split (request.META [ 'PATH_INFO'])`
ben author

@Ben 두 줄을 사용하고 있습니다 referer = request.META.get ( 'HTTP_REFERER', '') test = referer.split (request.META [ 'PATH_INFO']). 나는 HTTP_REFERER에 대해별로 관심이 없다. HTTP_REFERER가없는 경우이 줄에서 문제가 완전히 수정됩니까?
the_game 2012 년

@the_game 예, 존재하지 않는 키에 액세스하기 위해 대괄호를 KeyError사용하면 dict의 get()메서드를 사용하면 기본값을 지정할 수 있습니다. split ()이 던지지 않도록 기본값을 빈 문자열로 지정했습니다 AttributeError. 그게 다야.
ben 작성자

@Ben. 그것은 나를 위해 일해 주셔서 감사합니다. 또한이 질문에 대답 할 수 있습니까? 이것이이 질문에 대한 확장이라고 생각합니다 . stackoverflow.com/questions/10410982/… . 이에 대한 해결책을 제게 제공해 주시겠습니까?
the_game

1
이것은 잘 작동합니다. 하지만 has_key()대신 사용되지 않습니다 key in d. 그러나 나는 당신이 ha22109의 대답에서 방금 가져온 것을 압니다. 한 가지 질문 : (더 짧게) request.META['PATH_INFO']사용할 수 있는데 왜 사용 request.path_info합니까?
Nick

19

나는이 질문이 지금 꽤 오래되었지만 여전히 유효하다는 것을 알고 있습니다. 이것이 가장 올바른 방법이라고 생각합니다. 본질적으로 Greg의 방법과 동일하지만 쉽게 재사용 할 수 있도록 확장 가능한 클래스로 공식화되었습니다.

from django.contrib.admin import SimpleListFilter
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _

class DefaultListFilter(SimpleListFilter):
    all_value = '_all'

    def default_value(self):
        raise NotImplementedError()

    def queryset(self, request, queryset):
        if self.parameter_name in request.GET and request.GET[self.parameter_name] == self.all_value:
            return queryset

        if self.parameter_name in request.GET:
            return queryset.filter(**{self.parameter_name:request.GET[self.parameter_name]})

        return queryset.filter(**{self.parameter_name:self.default_value()})

    def choices(self, cl):
        yield {
            'selected': self.value() == self.all_value,
            'query_string': cl.get_query_string({self.parameter_name: self.all_value}, []),
            'display': _('All'),
        }
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == force_text(lookup) or (self.value() == None and force_text(self.default_value()) == force_text(lookup)),
                'query_string': cl.get_query_string({
                    self.parameter_name: lookup,
                }, []),
                'display': title,
            }

class StatusFilter(DefaultListFilter):
    title = _('Status ')
    parameter_name = 'status__exact'

    def lookups(self, request, model_admin):
        return ((0,'activate'), (1,'pending'), (2,'rejected'))

    def default_value(self):
        return 1

class MyModelAdmin(admin.ModelAdmin):
    list_filter = (StatusFilter,)

8

리디렉션을 사용하는 일반적인 솔루션은 다음과 같습니다. GET 매개 변수가 있는지 확인하고, 존재하지 않으면 기본 get 매개 변수로 리디렉션합니다. 또한 list_filter 세트가 있으므로이를 선택하고 기본값을 표시합니다.

from django.shortcuts import redirect

class MyModelAdmin(admin.ModelAdmin):   

    ...

    list_filter = ('status', )

    def changelist_view(self, request, extra_context=None):
        referrer = request.META.get('HTTP_REFERER', '')
        get_param = "status__exact=5"
        if len(request.GET) == 0 and '?' not in referrer:
            return redirect("{url}?{get_parms}".format(url=request.path, get_parms=get_param))
        return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context)

유일한주의 사항은 "?"가있는 페이지로 직접 이동할 때입니다. URL에 HTTP_REFERER가 설정되어 있지 않으므로 기본 매개 변수와 리디렉션을 사용합니다. 이것은 나에게 좋습니다. 관리자 필터를 클릭하면 훌륭하게 작동합니다.

업데이트 :

주의 사항을 피하기 위해 changelist_view 기능을 단순화하는 사용자 지정 필터 함수를 작성했습니다. 필터는 다음과 같습니다.

class MyModelStatusFilter(admin.SimpleListFilter):
    title = _('Status')
    parameter_name = 'status'

    def lookups(self, request, model_admin):  # Available Values / Status Codes etc..
        return (
            (8, _('All')),
            (0, _('Incomplete')),
            (5, _('Pending')),
            (6, _('Selected')),
            (7, _('Accepted')),
        )

    def choices(self, cl):  # Overwrite this method to prevent the default "All"
        from django.utils.encoding import force_text
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == force_text(lookup),
                'query_string': cl.get_query_string({
                    self.parameter_name: lookup,
                }, []),
                'display': title,
            }

    def queryset(self, request, queryset):  # Run the queryset based on your lookup values
        if self.value() is None:
            return queryset.filter(status=5)
        elif int(self.value()) == 0:
            return queryset.filter(status__lte=4)
        elif int(self.value()) == 8:
            return queryset.all()
        elif int(self.value()) >= 5:
            return queryset.filter(status=self.value())
        return queryset.filter(status=5)

이제 changelist_view는 아무것도없는 경우에만 기본 매개 변수를 전달합니다. 아이디어는 get 매개 변수를 사용하지 않고 모두보기 위해 제네릭 필터 기능을 제거하는 것이 었습니다. 모든 것을 보려면 해당 목적을 위해 상태 = 8을 할당했습니다. :

class MyModelAdmin(admin.ModelAdmin):   

    ...

    list_filter = ('status', )

    def changelist_view(self, request, extra_context=None):
        if len(request.GET) == 0:
            get_param = "status=5"
            return redirect("{url}?{get_parms}".format(url=request.path, get_parms=get_param))
        return super(MyModelAdmin, self).changelist_view(request, extra_context=extra_context)

내 경고, 사용자 지정 필터에 대한 수정 사항이 있습니다. 대체 솔루션으로 제시하겠습니다.
radtek 2014 년

감사합니다. 리디렉션이 가장 깨끗하고 가장 간단한 솔루션이라는 것을 알았습니다. 나는 또한 "주의 사항"을 이해하지 못합니다. 클릭하거나 직접 링크를 사용하여 항상 원하는 결과를 얻습니다 (사용자 지정 필터를 사용하지 않았습니다).
Dennis Golomazov 2015

6
def changelist_view( self, request, extra_context = None ):
    default_filter = False
    try:
        ref = request.META['HTTP_REFERER']
        pinfo = request.META['PATH_INFO']
        qstr = ref.split( pinfo )

        if len( qstr ) < 2:
            default_filter = True
    except:
        default_filter = True

    if default_filter:
        q = request.GET.copy()
        q['registered__exact'] = '1'
        request.GET = q
        request.META['QUERY_STRING'] = request.GET.urlencode()

    return super( InterestAdmin, self ).changelist_view( request, extra_context = extra_context )

4

SimpleListFilter의 return queryset.filter()or if self.value() is None및 Override 메서드를 간단히 사용할 수 있습니다.

from django.utils.encoding import force_text

def choices(self, changelist):
    for lookup, title in self.lookup_choices:
        yield {
            'selected': force_text(self.value()) == force_text(lookup),
            'query_string': changelist.get_query_string(
                {self.parameter_name: lookup}, []
            ),
            'display': title,
        }

3

필터 값을 미리 선택하는 대신 관리자에 표시하기 전에 항상 데이터를 미리 필터링하려면 ModelAdmin.queryset()대신 메서드를 재정의해야 합니다.


이것은 여전히 ​​문제를 일으킬 수 있지만 꽤 깨끗하고 빠른 솔루션입니다. 관리자에서 필터링 옵션이 활성화되면 사용자는 겉보기에 잘못된 결과를 얻을 수 있습니다. 재정의 된 쿼리 세트에 .exclude () 절이 포함 된 경우 해당 레코드는 나열되지 않지만 명시 적으로 표시하는 관리자 필터링 옵션은 여전히 ​​관리 UI에서 제공됩니다.
Tomas Andrle

OP가 위의 @TomasAndrle이 지적한 것처럼 쿼리 세트가 잘못된 솔루션이 될 필터를 넣을 것을 분명히 요청했기 때문에이 상황에 적용되는 더 낮은 투표로 다른 정답이 있습니다.
eskhool

@eskhool을 지적 해 주셔서 감사합니다. 제 답변을 0으로 낮추려고했지만 자신을 낮추는 것이 허용되지 않는 것 같습니다.
akaihola

3

DjangoChoices, Python> = 2.5 및 물론 Django> = 1.4를 사용하는 Greg의 답변에 대한 약간의 개선.

from django.utils.translation import ugettext_lazy as _
from django.contrib.admin import SimpleListFilter

class OrderStatusFilter(SimpleListFilter):
    title = _('Status')

    parameter_name = 'status__exact'
    default_status = OrderStatuses.closed

    def lookups(self, request, model_admin):
        return (('all', _('All')),) + OrderStatuses.choices

    def choices(self, cl):
        for lookup, title in self.lookup_choices:
            yield {
                'selected': self.value() == lookup if self.value() else lookup == self.default_status,
                'query_string': cl.get_query_string({self.parameter_name: lookup}, []),
                'display': title,
            }

    def queryset(self, request, queryset):
        if self.value() in OrderStatuses.values:
            return queryset.filter(status=self.value())
        elif self.value() is None:
            return queryset.filter(status=self.default_status)


class Admin(admin.ModelAdmin):
    list_filter = [OrderStatusFilter] 

좋은 솔루션에 대한 Greg에게 감사드립니다!


2

이것이 최선의 해결책이 아니라는 것을 알고 있지만 다음과 같이 관리 템플릿, 줄 25 및 37에서 index.html을 변경했습니다.

25 : <th scope="row"><a href="{{ model.admin_url }}{% ifequal model.name "yourmodelname" %}?yourflag_flag__exact=1{% endifequal %}">{{ model.name }}</a></th>

37 : <td><a href="{{ model.admin_url }}{% ifequal model.name "yourmodelname" %}?yourflag__exact=1{% endifequal %}" class="changelink">{% trans 'Change' %}</a></td>


1

필터링이 제대로 작동하도록 수정해야했습니다. 페이지가로드 될 때 이전 솔루션이 저에게 효과적이었습니다. '조치'가 수행되면 필터가 기본값이 아닌 '모두'로 돌아갑니다. 이 솔루션은 기본 필터를 사용하여 관리자 변경 페이지를로드하지만 페이지에서 다른 활동이 발생할 때 필터 변경 또는 현재 필터도 유지합니다. 모든 사례를 테스트하지는 않았지만 실제로는 페이지가로드 될 때만 발생하도록 기본 필터 설정을 제한 할 수 있습니다.

def changelist_view(self, request, extra_context=None):
    default_filter = False

    try:
        ref = request.META['HTTP_REFERER']
        pinfo = request.META['PATH_INFO']
        qstr = ref.split(pinfo)
        querystr = request.META['QUERY_STRING']

        # Check the QUERY_STRING value, otherwise when
        # trying to filter the filter gets reset below
        if querystr is None:
            if len(qstr) < 2 or qstr[1] == '':
                default_filter = True
    except:
        default_filter = True

    if default_filter:
        q = request.GET.copy()
        q['registered__isnull'] = 'True'
        request.GET = q
        request.META['QUERY_STRING'] = request.GET.urlencode()

    return super(MyAdmin, self).changelist_view(request, extra_context=extra_context)

1

약간의 주제에서 벗어 났지만 비슷한 질문에 대한 검색이 나를 여기로 이끌었습니다. 나는 날짜별로 기본 쿼리를 찾고 있었는데 (즉, 입력이 제공되지 않으면 timestamp'Today'가있는 개체 만 표시 ) 질문이 약간 복잡해졌습니다. 내가 생각해 낸 것은 다음과 같습니다.

from django.contrib.admin.options import IncorrectLookupParameters
from django.core.exceptions import ValidationError

class TodayDefaultDateFieldListFilter(admin.DateFieldListFilter):
    """ If no date is query params are provided, query for Today """

    def queryset(self, request, queryset):
        try:
            if not self.used_parameters:
                now = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
                self.used_parameters = {
                    ('%s__lt' % self.field_path): str(now + datetime.timedelta(days=1)),
                    ('%s__gte' % self.field_path): str(now),
                }
                # Insure that the dropdown reflects 'Today'
                self.date_params = self.used_parameters
            return queryset.filter(**self.used_parameters)
        except ValidationError, e:
            raise IncorrectLookupParameters(e)

class ImagesAdmin(admin.ModelAdmin):
    list_filter = (
        ('timestamp', TodayDefaultDateFieldListFilter),
    )

이것은 기본 DateFieldListFilter. 설정 self.date_params하면 필터 드롭 다운이 self.used_parameters. 이러한 이유로이 self.used_parameters드롭 다운 선택 항목 중 하나에서 사용되는 것과 정확히 일치하는지 확인해야합니다 (예 : date_params'오늘'또는 '지난 7 일'을 사용할 때가 무엇인지 찾아서 self.used_parameters일치하도록 구성 ).

이것은 Django 1.4.10에서 작동하도록 제작되었습니다.


1

이것은 오래된 스레드 일 수 있지만 Google 검색에서 더 나은 답변을 찾을 수 없으므로 솔루션을 추가 할 것이라고 생각했습니다.

Changelist_view에 대한 ModelAdmin에서 답변 한 내용 (Deminic Rodger 또는 ha22109인지 확실하지 않음)을 수행합니다.

class MyModelAdmin(admin.ModelAdmin):   
    list_filter = (CustomFilter,)

    def changelist_view(self, request, extra_context=None):

        if not request.GET.has_key('decommissioned__exact'):

            q = request.GET.copy()
            q['decommissioned__exact'] = 'N'
            request.GET = q
            request.META['QUERY_STRING'] = request.GET.urlencode()
        return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context)

그런 다음 사용자 지정 SimpleListFilter를 만들어야합니다.

class CustomFilter(admin.SimpleListFilter):
    title = 'Decommissioned'
    parameter_name = 'decommissioned'  # i chose to change it

def lookups(self, request, model_admin):
    return (
        ('All', 'all'),
        ('1', 'Decommissioned'),
        ('0', 'Active (or whatever)'),
    )

# had to override so that we could remove the default 'All' option
# that won't work with our default filter in the ModelAdmin class
def choices(self, cl):
    yield {
        'selected': self.value() is None,
        'query_string': cl.get_query_string({}, [self.parameter_name]),
        # 'display': _('All'),
    }
    for lookup, title in self.lookup_choices:
        yield {
            'selected': self.value() == lookup,
            'query_string': cl.get_query_string({
                self.parameter_name: lookup,
            }, []),
            'display': title,
        }

def queryset(self, request, queryset):
    if self.value() == '1':
        return queryset.filter(decommissioned=1)
    elif self.value() == '0':
        return queryset.filter(decommissioned=0)
    return queryset

선택 함수의 yield call에서 'force_text'(일명 force_unicode) 함수를 사용해야한다는 것을 알았습니다. 그렇지 않으면 선택한 필터 옵션이 '선택됨'으로 표시되지 않습니다. 즉, " '선택됨': self.value () == force_text (lookup),"
MagicLAMP

1

다음은 재정의 된 '모두'와 기본값이 선택된 필터를 생성 할 수있는 가장 깨끗한 버전입니다.

기본적으로 표시되는 경우 현재 진행중인 여행이 표시됩니다.

class HappeningTripFilter(admin.SimpleListFilter):
    """
    Filter the Trips Happening in the Past, Future or now.
    """
    default_value = 'now'
    title = 'Happening'
    parameter_name = 'happening'

    def lookups(self, request, model_admin):
        """
        List the Choices available for this filter.
        """
        return (
            ('all', 'All'),
            ('future', 'Not yet started'),
            ('now', 'Happening now'),
            ('past', 'Already finished'),
        )

    def choices(self, changelist):
        """
        Overwrite this method to prevent the default "All".
        """
        value = self.value() or self.default_value
        for lookup, title in self.lookup_choices:
            yield {
                'selected': value == force_text(lookup),
                'query_string': changelist.get_query_string({
                    self.parameter_name: lookup,
                }, []),
                'display': title,
            }

    def queryset(self, request, queryset):
        """
        Returns the Queryset depending on the Choice.
        """
        value = self.value() or self.default_value
        now = timezone.now()
        if value == 'future':
            return queryset.filter(start_date_time__gt=now)
        if value == 'now':
            return queryset.filter(start_date_time__lte=now, end_date_time__gte=now)
        if value == 'past':
            return queryset.filter(end_date_time__lt=now)
        return queryset.all()

0

여기에있는 일부 답변 (대부분 Greg 's)에서 영감을 받아 재사용 가능한 Filter 하위 클래스를 만들었습니다.

장점 :

재사용 가능 -모든 표준 ModelAdmin클래스 에서 플러그 가능

확장 가능 - QuerySet필터링을 위한 추가 / 사용자 지정 로직 추가 용이

사용하기 쉬움 -가장 기본적인 형태에서는 하나의 사용자 지정 속성과 하나의 사용자 지정 메서드 만 구현하면됩니다 (SimpleListFilter 서브 클래 싱에 필요한 것 제외).

직관적 인 관리자 - "전체"필터 링크가 예상대로 작동합니다. 다른 모든 사람들과 마찬가지로

리디렉션 없음 - GET요청 페이로드 HTTP_REFERER(또는 기본 형식의 기타 요청 관련 항목)에 관계없이 검사 할 필요가 없습니다.

(변경 목록) 뷰 조작 없음 -템플릿 조작 없음 (신은 금지)

암호:

(대부분의는 import유형 힌트 및 예외를위한 것입니다)

from typing import List, Tuple, Any

from django.contrib.admin.filters import SimpleListFilter
from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.admin.views.main import ChangeList
from django.db.models.query import QuerySet
from django.utils.encoding import force_str
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError


class PreFilteredListFilter(SimpleListFilter):

    # Either set this or override .get_default_value()
    default_value = None

    no_filter_value = 'all'
    no_filter_name = _("All")

    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = None

    # Parameter for the filter that will be used in the URL query.
    parameter_name = None

    def get_default_value(self):
        if self.default_value is not None:
            return self.default_value
        raise NotImplementedError(
            'Either the .default_value attribute needs to be set or '
            'the .get_default_value() method must be overridden to '
            'return a URL query argument for parameter_name.'
        )

    def get_lookups(self) -> List[Tuple[Any, str]]:
        """
        Returns a list of tuples. The first element in each
        tuple is the coded value for the option that will
        appear in the URL query. The second element is the
        human-readable name for the option that will appear
        in the right sidebar.
        """
        raise NotImplementedError(
            'The .get_lookups() method must be overridden to '
            'return a list of tuples (value, verbose value).'
        )

    # Overriding parent class:
    def lookups(self, request, model_admin) -> List[Tuple[Any, str]]:
        return [(self.no_filter_value, self.no_filter_name)] + self.get_lookups()

    # Overriding parent class:
    def queryset(self, request, queryset: QuerySet) -> QuerySet:
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        if self.value() is None:
            return self.get_default_queryset(queryset)
        if self.value() == self.no_filter_value:
            return queryset.all()
        return self.get_filtered_queryset(queryset)

    def get_default_queryset(self, queryset: QuerySet) -> QuerySet:
        return queryset.filter(**{self.parameter_name: self.get_default_value()})

    def get_filtered_queryset(self, queryset: QuerySet) -> QuerySet:
        try:
            return queryset.filter(**self.used_parameters)
        except (ValueError, ValidationError) as e:
            # Fields may raise a ValueError or ValidationError when converting
            # the parameters to the correct type.
            raise IncorrectLookupParameters(e)

    # Overriding parent class:
    def choices(self, changelist: ChangeList):
        """
        Overridden to prevent the default "All".
        """
        value = self.value() or force_str(self.get_default_value())
        for lookup, title in self.lookup_choices:
            yield {
                'selected': value == force_str(lookup),
                'query_string': changelist.get_query_string({self.parameter_name: lookup}),
                'display': title,
            }

전체 사용 예 :

from django.contrib import admin
from .models import SomeModelWithStatus


class StatusFilter(PreFilteredListFilter):
    default_value = SomeModelWithStatus.Status.FOO
    title = _('Status')
    parameter_name = 'status'

    def get_lookups(self):
        return SomeModelWithStatus.Status.choices


@admin.register(SomeModelWithStatus)
class SomeModelAdmin(admin.ModelAdmin):
    list_filter = (StatusFilter, )

이것이 누군가에게 도움이되기를 바랍니다. 피드백은 항상 감사합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.