Django yöneticisinde varsayılan filtre


94

Varsayılan filtre seçeneğini 'TÜMÜ' olarak nasıl değiştirebilirim? Ben olarak adlandırılan bir alan statusüç değeri olan: activate, pendingve rejected. list_filterDjango admin'de kullandığımda , filtre varsayılan olarak 'Tümü' olarak ayarlandı, ancak varsayılan olarak beklemede olarak ayarlamak istiyorum.

Yanıtlar:


105

Bunu başarmak ve kenar çubuğunuzda kullanılabilir bir 'Tümü' bağlantısına sahip olmak için (yani beklemede göstermek yerine tümünü gösteren), django.contrib.admin.filters.SimpleListFiltervarsayılan olarak 'beklemeden' devralan ve filtreleyen özel bir liste filtresi oluşturmanız gerekir . Bu satırlardaki bir şey çalışmalıdır:

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] 

DÜZENLEME: Django 1.4 gerektirir (teşekkürler Simon)


3
Bu en temiz çözümdür, ancak yine de en az olumlu oyu vardır ... Django 1.4 gerektirir, ancak şimdiye kadar verilmesi gerekir.
Simon

@Greg Filtre ve filtre sekmesinin işlevselliğini yönetici sayfasından tamamen nasıl kaldırırsınız ?


2
Bu çözümün küçük bir dezavantajı vardır. Filtreler boş olduğunda (aslında 'beklemede' filtre kullanıldı), Django 1.8 yanlış bir şekilde tam sonuç sayısını belirler ve show_full_result_count True ise (varsayılan olarak) sonuç sayısını göstermez . -
Alexander Fedotov

Çözümdeki choicesyöntemi geçersiz kılmayı başaramazsanız , sinir bozucu bir şekilde seçenekler listesinin en üstüne kendi Tümü seçeneğini eklemeye devam edeceğini unutmayın .
richard

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
Bu çözümün dezavantajı, "Tümü" seçeneğinin kullanıcı arayüzünde hala görüntülenmesine rağmen, seçildiğinde varsayılan filtrelemeyi hala uyguluyor olmasıdır.
akaihola

aynı sorum var, ama tekrarı anlayabiliyorum ... Özür dilerim Django ile yeniyim
Asinox

Bu iyi ama url'de get parametresini görmem gerekiyordu, böylece filtrem onu ​​alıp seçti. Çözümümü kısa süre içinde gönderiyorum.
radtek

açıklama eksik. sadece bir kod parçası göndermek herkese yardımcı olmayabilir.
Üstelik

19

Ve karşılaştırarak "All" seçimine izin veren modifiye yukarıdaki ha22109 cevabını aldı HTTP_REFERERve 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
Bu benim için bozuldu çünkü HTTP_REFERER her zaman mevcut değildi. 'Referer = request.META.get (' HTTP_REFERER ',' ') yaptım; test = referer.split (request.META ['PATH_INFO']) `
ben yazar

@Ben iki satırlık referer = request.META.get ('HTTP_REFERER', '') test = referer.split (request.META ['PATH_INFO']) kullanıyorum. HTTP_REFERER hakkında pek bir şey bilmiyorum. HTTP_REFERER yoksa sorun bu satırlardan tamamen giderildi mi?
the_game

@the_game evet, fikir şu ki, var olmayan bir anahtara erişmek için köşeli parantezler kullanırsanız, atar KeyError, dict'in get()yöntemini kullanırsanız bir varsayılan belirtebilirsiniz. Split () atmasın diye varsayılan bir boş dizge belirledim AttributeError. Bu kadar.
ben yazar

@Ben. Teşekkürler benim için çalışıyor. Ayrıca bu soruyu yanıtlayabilir misiniz, bunun bu sorunun bir uzantısı olduğuna inanıyorum, yalnızca stackoverflow.com/questions/10410982/… . Lütfen bana bunun için bir çözüm sağlar mısınız?
the_game

1
Bu iyi çalışıyor. yine has_key()de lehine kullanımdan kaldırıldı key in d. Ama ha22109'un cevabını aldığını biliyorum. Bir soru: request.META['PATH_INFO']sadece request.path_info(daha kısa) kullanabileceğiniz zaman neden kullanıyorsunuz ?
Nick

19

Bu sorunun şu anda oldukça eski olduğunu biliyorum, ama hala geçerli. Bunun bunu yapmanın en doğru yolu olduğuna inanıyorum. Temelde Greg'in yöntemiyle aynıdır, ancak kolay yeniden kullanım için genişletilebilir bir sınıf olarak formüle edilmiştir.

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

İşte yeniden yönlendirmeyi kullanan genel çözümüm, sadece herhangi bir GET parametresi olup olmadığını kontrol ediyor, yoksa varsayılan get parametresi ile yönlendiriyor. Ayrıca bir list_filter setim var, bu yüzden onu alıyor ve varsayılanı gösteriyor.

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)

Tek uyarı, sayfaya "?" İle doğrudan eriştiğiniz zamandır. url'de mevcutsa, ayarlanan HTTP_REFERER yoktur, bu nedenle varsayılan parametreyi ve yönlendirmeyi kullanır. Bu benim için iyi, yönetici filtresini tıkladığınızda harika çalışıyor.

GÜNCELLEME :

Uyarıyı aşmak için, changelist_view işlevselliğini basitleştiren özel bir filtre işlevi yazdım. İşte filtre:

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)

Ve changelist_view artık varsayılan parametreyi yalnızca hiçbiri yoksa geçer. Buradaki fikir, hiçbir get parametresi kullanmadan tümünü görüntülemek için jenerik filtreler özelliğinden kurtulmaktı. Tüm atadığım durumu görüntülemek için = 8 bu amaç için:

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)

Uyarı için bir düzeltmem var, özel bir filtre. Bunu alternatif bir çözüm olarak sunacağım.
radtek

Teşekkürler, yönlendirmeyi en temiz ve en basit çözüm buluyorum. Ayrıca "ihtar" ı da anlamıyorum. İster doğrudan tıklayarak ister doğrudan bağlantı kullanarak istediğim sonucu elde ederim (özel filtreyi kullanmadım).
Dennis Golomazov

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'in basitçe return queryset.filter()veya if self.value() is Noneve Override yöntemini kullanabilirsiniz .

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

Bir filtre değerini önceden seçmek yerine, verileri yöneticide göstermeden önce her zaman önceden filtrelemek istiyorsanız, ModelAdmin.queryset()bunun yerine yöntemi geçersiz kılmanız gerektiğini unutmayın .


Yine de sorunlara neden olsa da bu oldukça temiz ve hızlı bir çözümdür. Yöneticide filtreleme seçenekleri etkinleştirildiğinde, kullanıcı görünüşte yanlış sonuçlar alabilir. Geçersiz kılma sorgu kümesi bir .exclude () yan tümcesi içeriyorsa, bunun tarafından yakalanan kayıtlar hiçbir zaman listelenmez, ancak bunları açıkça göstermek için yönetici filtreleme seçenekleri yine de yönetici kullanıcı arabirimi tarafından sunulacaktır.
Tomas Andrle

OP, yukarıda @TomasAndrle tarafından da belirtildiği gibi bir sorgu setinin yanlış çözüm olacağı bir filtre koymasını açıkça talep ettiğinden, bu duruma uygulanan daha düşük oylarla daha doğru cevaplar da var.
eskhool

Bunu @eskhool'a işaret ettiğiniz için teşekkürler, cevabımı sıfıra düşürmeye çalıştım ama görünüşe göre kendi kendine olumsuz oy vermesine izin verilmiyor.
akaihola

3

Greg'in DjangoChoices, Python> = 2.5 ve tabii ki Django> = 1.4 kullanarak cevabında küçük bir gelişme.

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] 

Güzel çözüm için Greg'e teşekkürler!


2

Bunun en iyi çözüm olmadığını biliyorum, ancak yönetici şablonundaki index.html'yi şu şekilde değiştirdim, satır 25 ve 37:

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

Filtrelemenin doğru çalışması için bir değişiklik yapmam gerekiyordu. Önceki çözüm, sayfa yüklendiğinde benim için çalıştı. Bir 'eylem' gerçekleştirildiyse, filtre varsayılan değerime değil, 'Tümü'ne geri döndü. Bu çözüm, yönetici değişiklik sayfasını varsayılan filtre ile yükler, ancak aynı zamanda sayfada başka bir etkinlik gerçekleştiğinde filtre değişikliklerini veya geçerli filtreyi korur. Tüm vakaları test etmedim, ancak gerçekte bu, varsayılan bir filtre ayarını yalnızca sayfa yüklendiğinde gerçekleşecek şekilde sınırlıyor olabilir.

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

Biraz konu dışı ama benzer bir soru arayışım beni buraya getirdi. Tarihe göre varsayılan bir sorguya sahip olmak istiyordum (yani, herhangi bir girdi sağlanmadıysa, yalnızca timestampsoruyu biraz karmaşıklaştıran 'Bugün' olan nesneleri gösterin ). İşte bulduğum şey:

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

Bu, varsayılanın basit bir şekilde geçersiz kılınmasıdır DateFieldListFilter. Ayarına göre self.date_params, bu filtre açılır maçları için ne olursa olsun seçenek güncelleyecektir sigortalanır self.used_parameters. Bu nedenle, self.used_parameterstam olarak bu açılır seçimlerden biri tarafından kullanılacağından emin olmalısınız (yani, date_params'Bugün' veya 'Son 7 Gün'ü kullanırken ne olacağını öğrenin ve bunlarla self.used_parameterseşleşecek şekilde oluşturun).

Bu, Django 1.4.10 ile çalışmak üzere oluşturuldu


1

Bu eski bir konu olabilir, ancak google aramalarında daha iyi cevaplar bulamadığım için çözümümü ekleyeceğimi düşündüm.

Changelist_view için ModelAdmin'de Deminic Rodger'ın veya ha22109'un yanıt verip vermediğinden emin değilim

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)

O zaman özel bir SimpleListFilter oluşturmamız gerekir.

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

Seçenekler işlevindeki getiri çağrısında 'force_text' (aka force_unicode) işlevini kullanmam gerektiğini buldum, aksi takdirde seçilen filtre seçeneği 'seçili' olarak görünmezdi. Yani "'seçildi': self.value () == force_text (arama),"
MagicLAMP

1

İşte yeniden tanımlanmış bir 'Tümü' ve seçilen bir Varsayılan değere sahip bir filtre oluşturabildiğim En Temiz sürüm.

Varsayılan olarak bana şu anda gerçekleşen Gezileri gösteriyorsa.

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

Buradaki bazı cevaplardan (çoğunlukla Greg'in) esinlenerek yeniden kullanılabilir bir Filtre alt sınıfı oluşturdu.

Avantajlar:

Yeniden kullanılabilir - Herhangi bir standart ModelAdminsınıfta takılabilir

Genişletilebilir - QuerySetFiltreleme için ek / özel mantık eklemek kolaydır

Kullanımı kolay - En temel biçiminde, yalnızca bir özel öznitelik ve bir özel yöntemin uygulanması gerekir (SimpleListFilter alt sınıflandırma için gerekli olanların dışında)

Sezgisel yönetici - "Tümü" filtre bağlantısı beklendiği gibi çalışıyor; diğerleri gibi

Yeniden yönlendirme yok - GETİstek yükünü incelemeye gerek yok , HTTP_REFERERbunlardan bağımsız (veya temel biçimiyle taleple ilgili diğer şeyler)

Hayır (değişiklik listesi) görünüm manipülasyonu - Ve şablon manipülasyonu yok (tanrı korusun)

Kod:

( importURL'lerin çoğu yalnızca yazı ipuçları ve istisnalar içindir)

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,
            }

Tam kullanım örneği:

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

Umarım bu birisine yardımcı olur; geri bildirim her zaman takdir edilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.