জ্যাঙ্গো প্রশাসকের ডিফল্ট ফিল্টার


94

আমি কীভাবে 'সব' থেকে ডিফল্ট ফিল্টার পছন্দটি পরিবর্তন করতে পারি? কারণ আমি একটা ক্ষেত নামকরণ আছে statusযা তিন মান রয়েছে: activate, pendingএবং rejected। আমি যখন list_filterজ্যাঙ্গো অ্যাডমিনে ব্যবহার করি , ফিল্টারটি ডিফল্টরূপে 'সমস্ত' এ সেট হয় তবে আমি ডিফল্টরূপে এটিকে মুলতুবিতে সেট করতে চাই।

উত্তর:


105

অর্ডার এই অর্জন করার জন্য এবং (অর্থাত যে শো সব বদলে মুলতুবী দেখাচ্ছে), আপনি একটি কাস্টম তালিকা ফিল্টার তৈরি করতে থেকে inheriting প্রয়োজন চাই একটি ব্যবহারযোগ্য 'সমস্ত' আপনার সাইডবারে লিঙ্কটি আছে 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] 

সম্পাদনা: জাজানো 1.4 প্রয়োজন (ধন্যবাদ সাইমন)


4
এটি সকলের মধ্যে পরিষ্কার সমাধান, তবুও এর কয়েকটি সংখ্যক অগ্রগতি রয়েছে ... এটির জন্য জ্যাঙ্গো 1.4 প্রয়োজন, যদিও এটি এখনই দেওয়া উচিত।
সাইমন

@ গ্রেগ আপনি অ্যাডমিন পৃষ্ঠার বাইরে ফিল্টার এবং ফিল্টার ট্যাবটির কার্যকারিতা কীভাবে মুছে ফেলবেন ?


4
এই দ্রষ্টব্যটির একটি ছোট্ট অপূর্ণতা রয়েছে। ফিল্টারগুলি ফাঁকা থাকলে (প্রকৃতপক্ষে 'মুলতুবি' ফিল্টার ব্যবহার করা হয়), জাজানো 1.8 ভুল ফলাফলের সাথে পুরো ফলাফল গণনাটি নির্ধারণ করে এবং show_full_result_count সত্য (ডিফল্টরূপে) হলে ফলাফল গণনা প্রদর্শন করে না । -
আলেকজান্ডার ফেদোটভ

দ্রষ্টব্য যে আপনি যদি choicesসমাধানটিতে পদ্ধতিটিকে ওভাররাইড করতে ব্যর্থ হন তবে এটি বিরক্তিকরভাবে পছন্দগুলির তালিকার শীর্ষে তার নিজস্ব সমস্ত বিকল্প যুক্ত করতে থাকবে ।
রিচার্ড

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
এই সমাধানটির একটি অপূর্ণতা রয়েছে যে "সমস্ত" পছন্দটি এখনও ইউআইতে প্রদর্শিত হয়, এটি নির্বাচন করা এখনও ডিফল্ট ফিল্টারিংয়ের জন্য প্রয়োগ করে।
আকাইহোলা

আমার একই প্রশ্ন রয়েছে, তবে আমি রিপ্লেটি
২০০৮ /

এটি ভাল তবে আমার ইউআরএলটিতে প্যারামিটারটি দেখার দরকার ছিল যাতে আমার ফিল্টারটি এটি বাছাই করতে পারে এবং এটি নির্বাচিত দেখায়। আমার সমাধানটি শীঘ্রই পোস্ট করা।
র‌্যাডটেক

ব্যাখ্যা অনুপস্থিত শুধু কোডের টুকরো পোস্ট করা প্রত্যেককে সাহায্য নাও করতে পারে। এটি শীর্ষে এটি কাজ করছে না এবং একটি সামান্য প্রেক্ষাপট ছাড়া এটি কেন খুঁজে পাওয়া কঠিন
এভিলস্মার্ফ

19

উপরের হাই 22109 এর উত্তর নিয়েছে এবং তুলনা করে 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)

4
এটি আমার জন্য ভেঙে গেছে কারণ HTTP_REFERER সর্বদা উপস্থিত ছিল না। আমি 'রেফারার = অনুরোধ করেছি M মেটা.গেট (' HTTP_REFERER ',' ')); পরীক্ষা = রেফারার.স্প্লিট (অনুরোধ.মেটা ['पथপথফো']) `
বেন লেখক

@ আমি আপনার দুটি লাইন রেফারার = অনুরোধ ব্যবহার করছি M.মেটা.গেট ('HTTP_REFERER', '') পরীক্ষা = রেফার.স্প্লিট (অনুরোধ.মেটা ['PATH_INFO'])। HTTP_REFERER সম্পর্কে আমি খুব বেশি কিছু করি না। HTTP_REFERER উপস্থিত না থাকলে এই লাইনগুলি থেকে কি সমস্যাটি পুরোপুরি ঠিক হয়ে গেছে?
the_game

@ গে_ হ্যাঁ, ধারণাটি হল আপনি যদি বিদ্যমান কোনও কীটি অ্যাক্সেস করার চেষ্টা করার জন্য বর্গাকার বন্ধনী KeyErrorব্যবহার করেন তবে এটি ছুঁড়ে যায় , যদি আপনি ডিকের get()পদ্ধতিটি ব্যবহার করেন তবে আপনি একটি ডিফল্ট নির্দিষ্ট করতে পারেন। আমি খালি স্ট্রিংয়ের একটি ডিফল্ট উল্লেখ করেছি যাতে বিভক্ত () ছোঁড়ে না AttributeError। এখানেই শেষ.
বেন লেখক 13

@ বেন .ধন্যবাদ এটি আমার পক্ষে কাজ করে। এছাড়াও আপনি এই প্রশ্নের জবাব দিতে পারেন আমি বিশ্বাস করি এটি কেবল এই প্রশ্নের একমাত্র প্রসারিত স্ট্যাকওভারফ্লো . com/Qtionstions/10410982/… । আপনি কি আমাকে এই জন্য একটি সমাধান প্রদান করতে পারেন?
the_game

4
এটি ভাল কাজ করে। যদিও এর has_key()পক্ষে হ্রাস করা হয় key in d। তবে আমি জানি আপনি স্রেফ হা 22109 এর উত্তরটি গ্রহণ করেছেন। একটি প্রশ্ন: request.META['PATH_INFO']আপনি যখন ব্যবহার করতে পারবেন তখন কেন ব্যবহার করবেন request.path_info(খাটো)?
নিক

19

আমি জানি এই প্রশ্নটি এখন বেশ পুরানো, তবে এটি এখনও বৈধ। আমি বিশ্বাস করি এটি এটি করার সবচেয়ে সঠিক উপায়। এটি মূলত গ্রেগের পদ্ধতির মতোই, তবে সহজেই পুনরায় ব্যবহারের জন্য প্রসারিত শ্রেণি হিসাবে তৈরি।

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

পুনঃনির্দেশ ব্যবহার করে আমার জেনেরিক সমাধানটি এখানে রয়েছে, এটি কোনও জিইটি পরামিতি রয়েছে কিনা তা পরীক্ষা করে দেখায়, যদি কোনওটি না থাকে তবে এটি ডিফল্ট গ্যারামিটি প্যারামিটারের সাথে পুনঃনির্দেশ করে। আমার কাছে একটি তালিকা_ ফিল্টার সেটও রয়েছে তাই এটি এটি বাছাই করে এবং ডিফল্টটি প্রদর্শন করে।

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)

কেবলমাত্র সতর্কতা যখন আপনি "" দিয়ে পৃষ্ঠাটিতে সরাসরি যাবেন? ইউআরএল-তে উপস্থিত, কোনও HTTP_REFERER সেট নেই তাই এটি ডিফল্ট প্যারামিটার ব্যবহার করবে এবং পুনর্নির্দেশ করবে। এটি আমার পক্ষে ঠিক আছে, আপনি যখন অ্যাডমিন ফিল্টারটি ক্লিক করেন এটি দুর্দান্ত কাজ করে।

আপডেট :

ক্যাভিয়েটের আশেপাশে যাওয়ার জন্য, আমি একটি কাস্টম ফিল্টার ফাংশন লিখেছি যা চেঞ্জলিস্ট_ভিউ কার্যকারিতা সরল করে তুলেছে। ফিল্টারটি এখানে:

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)

এবং চেঞ্জলিস্ট_ভিউ এখন উপস্থিত না থাকলে কেবলমাত্র ডিফল্ট প্যারামিটারটি পাস করে passes ধারণাটি হ'ল জেনেরিক্স ফিল্টারগুলির ক্ষমতা কোনও প্যারামিটার না পেয়ে সমস্ত কিছু দেখার ক্ষমতা থেকে মুক্তি পাবে। আমি সমস্ত সেই উদ্দেশ্যে স্থিতি = 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

আপনাকে ধন্যবাদ, আমি সবচেয়ে পরিষ্কার এবং সহজ সমাধান হিসাবে পুনর্নির্দেশ দেখতে পেয়েছি। আমি "ক্যাভিয়েট "ও বুঝতে পারি না। আমি সরাসরি লিঙ্ক ক্লিক করে বা ব্যবহার করে (আমি কাস্টম ফিল্টারটি ব্যবহার করি না) পছন্দসই ফলাফলটি পাই।
ডেনিস গোলোমাজোভ

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

আপনি কেবল সরললিস্টফিল্টার ব্যবহার করে return queryset.filter()বা if self.value() is Noneওভাররাইড পদ্ধতি করতে পারেন

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()তার পরিবর্তে আপনার পদ্ধতিটি ওভাররাইড করা উচিত ।


এটি একটি দুর্দান্ত পরিষ্কার এবং দ্রুত সমাধান যদিও এটি এখনও সমস্যার কারণ হতে পারে। যখন ফিল্টারিং বিকল্পগুলি প্রশাসকে সক্ষম করা থাকে তখন ব্যবহারকারী আপাতদৃষ্টিতে ভুল ফলাফল পেতে পারে। যদি ওভাররাইড ক্যোয়ারসেটে একটি। এক্সক্লুড () ধারা থাকে তবে তার দ্বারা ধরা রেকর্ডগুলি কখনই তালিকাভুক্ত হবে না তবে এডমিন ফিল্টারিং অপশনগুলি তাদের স্পষ্টভাবে দেখানোর জন্য অ্যাডমিন ইউআই অফার করবে।
টমাস অ্যান্ড্রেল

নিম্নের ভোটের সাথে আরও সঠিক সঠিক উত্তর রয়েছে যা এই অবস্থার সাথে প্রযোজ্য যেহেতু ওপি স্পষ্টভাবে অনুরোধ করেছে যে তিনি একটি ফিল্টার স্থাপন করতে যাচ্ছেন যা উপরের @ টমাসঅ্যান্ড্রেলের নির্দেশিত একটি ক্যোয়ারসেটটি ভুল সমাধান হতে পারে।
eskhool

@ ইখুলকে এটি দেখানোর জন্য ধন্যবাদ, আমি আমার উত্তরটি শূন্যের চেয়ে কমিয়ে দেওয়ার চেষ্টা করেছি তবে মনে হচ্ছে এটি নিজেকে হ্রাস করার অনুমতি নেই।
আকাইহোলা

3

জ্যাঙ্গোচোইসস, পাইথন> = 2.5 এবং অবশ্যই জ্যাঙ্গো> = 1.4 ব্যবহার করে গ্রেগের উত্তরে সামান্য উন্নতি।

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] 

দুর্দান্ত সমাধানের জন্য গ্রেগকে ধন্যবাদ!


2

আমি জানি যে এটি সর্বোত্তম সমাধান নয়, তবে আমি অ্যাডমিন টেমপ্লেটে সূচিপত্র html পরিবর্তন করেছি, 25 এবং 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

ফিল্টারিং সঠিকভাবে কাজ করতে আমাকে একটি পরিবর্তন করতে হয়েছিল। পূর্ববর্তী সমাধানটি পৃষ্ঠাটি লোড হওয়ার পরে আমার পক্ষে কাজ করেছিল। যদি কোনও 'ক্রিয়া' সম্পাদিত হয় তবে ফিল্টারটি আমার সমস্ত ডিফল্ট নয় বরং 'সমস্ত' এ ফিরে যায়। এই সমাধানটি অ্যাডমিন পরিবর্তন পৃষ্ঠাটি ডিফল্ট ফিল্টার সহ লোড করে, তবে যখন পৃষ্ঠায় অন্যান্য ক্রিয়াকলাপ ঘটে তখন ফিল্টার পরিবর্তনগুলি বা বর্তমান ফিল্টারটি বজায় রাখে। আমি সমস্ত ক্ষেত্রে পরীক্ষা করে দেখিনি, তবে বাস্তবে এটি কেবলমাত্র পৃষ্ঠা লোড হলেই কোনও ডিফল্ট ফিল্টারটি সেট করা সীমাবদ্ধ করে।

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'আজ' দিয়ে কেবলমাত্র বস্তুগুলি দেখান ), যা প্রশ্নটি কিছুটা জটিল করে তোলে। আমি এখানে যা এলাম:

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সেগুলির সাথে মেলে কাঠামোটি তৈরি করুন)।

এটি জাজানো 1.4.10 এর সাথে কাজ করার জন্য নির্মিত হয়েছিল


1

এটি একটি পুরানো থ্রেড হতে পারে তবে ভেবেছিল আমি গুগল অনুসন্ধানে আরও ভাল উত্তর খুঁজে না পাওয়ায় আমি আমার সমাধান যুক্ত করব।

চেঞ্জলিস্ট_ভিউয়ের জন্য মডেল অ্যাডমিনে কী (তার ডেমিনিক রজার, বা হা 22109 জবাব দিয়েছে তা নিশ্চিত নয়)

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)

তারপরে আমাদের একটি কাস্টম সিম্পললিস্ট ফিল্টার তৈরি করা দরকার

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

আমি খুঁজে পেয়েছি যে পছন্দগুলি ফাংশনে আমার 'ফোর্স_টেক্সট' (ওরফে ফোর্স_উনিকোড) ফাংশনটি ব্যবহার করতে হবে, অন্যথায় নির্বাচিত ফিল্টার বিকল্পটি 'নির্বাচিত' হিসাবে প্রদর্শিত হবে না। এটি "'নির্বাচিত': স্ব.মূল্য () == ফোর্স টেক্সট (চেহারা),"
ম্যাজিকলাম্প

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

এখানে কয়েকটি উত্তর (বেশিরভাগ গ্রেগের) দ্বারা অনুপ্রাণিত হয়ে পুনরায় ব্যবহারযোগ্য ফিল্টার উপ-শ্রেণি তৈরি করেছেন।

সুবিধাদি:

পুনরায় ব্যবহারযোগ্য - যে কোনও মানক ModelAdminক্লাসে প্লাগেবল

বর্ধনযোগ্য - QuerySetফিল্টারিংয়ের জন্য অতিরিক্ত / কাস্টম যুক্তি যুক্ত করা সহজ

সহজেই ব্যবহার করা যায় - এর সবচেয়ে মৌলিক আকারে, কেবল একটি কাস্টম বৈশিষ্ট্য এবং একটি কাস্টম পদ্ধতি প্রয়োগ করা প্রয়োজন (সিম্পললিস্টফিলার সাবক্লাসিংয়ের জন্য প্রয়োজনীয়গুলি বাদে)

স্বজ্ঞাত অ্যাডমিন - "সমস্ত" ফিল্টার লিঙ্কটি প্রত্যাশা অনুযায়ী কাজ করছে; অন্য সমস্ত যেমন হয়

কোনও পুনঃনির্দেশ নেই - GETঅনুরোধ পেইড, অজ্ঞেয়াদি HTTP_REFERER(বা অন্য কোনও অনুরোধ সম্পর্কিত জিনিসগুলি এর মূল আকারে) পরিদর্শন করার প্রয়োজন নেই

কোনও (পরিবর্তন তালিকা) ম্যানিপুলেশন দেখুন - এবং কোনও টেমপ্লেট ম্যানিপুলেশন (godশ্বর নিষেধ)

কোড:

(বেশিরভাগ 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.