2010-06-18 22 views
19

मैं जानता हूँ कि मैं पहले से ही ऐसा करने में कामयाब रहे, लेकिन याद नहीं कर सकते कि कैसे और न ही मैं इस बारे में कोई प्रलेखन नहीं मिल सकता है ..Django व्यवस्थापक डिफ़ॉल्ट फ़िल्टर

एक वस्तु सूची दृश्य पर डिफ़ॉल्ट रूप से एक फिल्टर लागू कर सकते हैं कैसे में व्यवस्थापक?

मेरे पास एक ऐप है जो उद्धरण सूची और उन उद्धरणों की स्थिति है (पूर्व: स्वीकृत, अस्वीकार, पकड़ पर ..)।

मैं फिल्टर स्थिति के बारे में सेट चाहते = क्वेरीसमूह क्या तुमने कभी करने में सक्षम नहीं होगा अधिभावी द्वारा डिफ़ॉल्ट है कि द्वारा 'स्वीकार किए जाते हैं' ..

+1

प्राप्त करने के लिए है सिर्फ इस प्रश्न के रिकॉर्ड के लिए [यहां सही ढंग से उत्तर दिया गया है] (http://stackoverflow.com/questions/851636/default-filter-in-django-admin/3783930#3783930) –

+1

संभावित डुप्लिकेट [Django व्यवस्थापक में डिफ़ॉल्ट फ़िल्टर] (https://stackoverflow.com/questions/851636/default-filter-in- django-admin) –

उत्तर

6

आप क्वेरीसमूह ओवरराइड कर सकते हैं

class QuoteAdmin(admin.ModelAdmin): 
    def get_queryset(self, request): 
     return super(QuoteAdmin,self).get_queryset(request).filter(status="accepted") 

हालांकि उन उद्धरणों को देखें जिनके पास "स्वीकृत" स्थिति नहीं है।

वैकल्पिक रूप से, आप निम्न यूआरएल से लिंक कर सकते हैं, फ़िल्टर को जीईटी पैरामीटर में जोड़ सकते हैं। व्यवस्थापक कक्षा में क्वेरीसमूह विधि काम नहीं करता है के साथ

def changelist_view(self, request, extra_context=None): 
    if not request.GET.has_key('status__exact'): 
     q = request.GET.copy() 
     q['status__exact'] = '1' 
     request.GET = q 
     request.META['QUERY_STRING'] = request.GET.urlencode() 
    return super(SoumissionAdmin,self).changelist_view(request, extra_context=extra_context) 

अन्य तरीके से,:

/admin/myapp/quote/?status=accepted 
7

अंत में, यह है कि क्या मैं खोज रहा था है। वास्तव में यह परिणाम फ़िल्टर करता है, लेकिन यह फ़िल्टर कार्यक्षमता टूटा हुआ छोड़ देता है।

समाधान मैंने पाया नहीं सही या तो यह है कि यह संभव है जब इसे का उपयोग "सभी/फिल्टर का चयन करने के लिए नहीं है। मेरे मामले में यह नाटकीय नहीं है और यह पर्याप्त है, हालांकि अच्छा होगा ..

2

मुझे लगता है कि मुझे उपयोगकर्ता को सीमित किए बिना ऐसा करने का कोई तरीका मिला है। यह निर्धारित करने के लिए कि क्या उपयोगकर्ता अभी इस पृष्ठ पर पहुंचा है, रेफरर को देखें। अगर ऐसा है तो आप उस फ़िल्टर पर आधारित डिफ़ॉल्ट यूआरएल पर रीडायरेक्ट करें।

def changelist_view(self, request, extra_context=None): 
    try: 
     test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO']) 
     if test and test[-1] and not test[-1].startswith('?') and not request.GET.has_key('status__exact'): 
      return HttpResponseRedirect("/admin/app/model/?status__exact=1") 
    except: pass # In case there is no referer 
    return super(MyModelAdmin,self).changelist_view(request, extra_context=extra_context) 
+0

यह काफी कठिन कोड हैक है, लेकिन यह उत्तर काम करता है। मैंने request.path के साथ "/ admin/app/model /" को प्रतिस्थापित करके इसे थोड़ा सा कम-हैक बनाया है और मेरे लिए http प्रतिक्रिया रीडायरेक्ट – Archie1986

17

थोड़ा और पुन: प्रयोज्य दृष्टिकोण:

class DefaultFilterMixIn(admin.ModelAdmin): 
    def changelist_view(self, request, *args, **kwargs): 
     from django.http import HttpResponseRedirect 
     if self.default_filters: 
      try: 
       test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO']) 
       if test and test[-1] and not test[-1].startswith('?'): 
        url = reverse('admin:%s_%s_changelist' % (self.opts.app_label, self.opts.module_name)) 
        filters = [] 
        for filter in self.default_filters: 
         key = filter.split('=')[0] 
         if not request.GET.has_key(key): 
          filters.append(filter) 
        if filters:       
         return HttpResponseRedirect("%s?%s" % (url, "&".join(filters))) 
      except: pass 
     return super(DefaultFilterMixIn, self).changelist_view(request, *args, **kwargs)    

और फिर बस अपने ModelAdmin पर एक default_filters को परिभाषित:

class YourModelAdmin(DefaultFilterMixIn): 
    .... 
    default_filters = ('snapshot__exact=0',) 
+0

भेजने से पहले "? Status__exact = 1" के बराबर समेकित किया है (जो हो सकता है अलग क्योंकि मैं django-grappelli का उपयोग कर रहा हूं) यह काम करता है लेकिन यह केवल तब होता है जब यह 'स्नैपशॉट = 0' है और' स्नैपशॉट__एक्सएक्ट = 0' नहीं है और साथ ही, किसी भी कारण से, फ़िल्टर अब और काम नहीं करते हैं और ऐसा इसलिए है क्योंकि जावास्क्रिप्ट है टूटा हुआ (कंसोल कहता है: "अनकही टाइप एरर: ऑब्जेक्ट [ऑब्जेक्ट ऑब्जेक्ट] में कोई विधि नहीं है ') और फिर यह गैप्रेलि के कारण हो सकता है। रन-ऑन वाक्य के लिए खेद है, लॉल। –

+0

django == 1.3.4 और grappelli == 2.3.9 के साथ मेरे लिए ठीक काम किया। मिश्रण के लिए प्रमुख प्रोप। –

+0

इस स्निपेट के लिए धन्यवाद, लेकिन यह पाइथन 3 और Django 1.9.7 के साथ काम नहीं करता है। बस अपवादों को शांत करना इतना अच्छा विचार नहीं है, इसलिए मैंने इसे टिप्पणी की। तब मैंने पाया कि self.opts.module_name इसके बजाय self.opts.model_name होना चाहिए और "' request.GET.has_key (key) '": "अनुरोध में कुंजी" द्वारा प्रतिस्थापित किया गया है। "(अद्यतन कोड बहुत लंबा यहां स्वीकार करने के लिए) –

1

यह मेरे लिए काम किया है और "सभी" समस्या h3 ने उल्लेख होने से बचा।

class MyAdmin(admin.ModelAdmin): 
    def changelist_view(self, request, extra_context=None): 
    referer = request.META.get('HTTP_REFERER', '') 
    showall = request.META['PATH_INFO'] in referer and not request.GET.has_key('timeframe') 
    if not showall and not request.GET.has_key('param_name_here'): 
     q = request.GET.copy() 
     q['param_name_here'] = 'default_value_here' 
     request.GET = q 
     request.META['QUERY_STRING'] = request.GET.urlencode() 
    return super(SerializableAdmin,self).changelist_view(request, extra_context=extra_context) 
5

मैंने इस समस्या को 'सब' समर्थन के साथ हल किया।

models.py में

: admin.py में

STATUSES_CHOICE = (
    ('0', 'Active'), 
    ('1', 'Deactive'), 
    ('2', 'Suspended'), 
) 

class Client(models.Model): 
    ... 
    status = models.IntegerField(verbose_name=_('Status'), 
           default=0, 
           db_index=True) 

:

class StatusAdminFilter(SimpleListFilter): 
    title = _('Status') 
    parameter_name = 'status' 
    all_param_value = 'all' 

    def lookups(self, request, model_admin): 
     return STATUSES_CHOICE 

    def queryset(self, request, queryset): 
     status = self.value() 
     try: 
      return (queryset if status == self.all_param_value else 
        queryset.filter(status=int(status))) 
     except ValueError: 
      raise Http404 

    def choices(self, cl): 
     yield {'selected': self.value() == self.all_param_value, 
       'query_string': cl.get_query_string(
        {self.parameter_name: self.all_param_value}, 
        [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} 


class ClientAdmin(admin.ModelAdmin): 
    list_filter = (StatusAdminFilter,) 

    def changelist_view(self, request, extra_context=None): 
     if not request.GET.has_key('status'): 
      q = request.GET.copy() 
      q['status'] = '0' # default value for status 
      request.GET = q 
      request.META['QUERY_STRING'] = request.GET.urlencode() 
     return super(ClientAdmin, self).changelist_view(
      request, extra_context=extra_context) 
+0

भलाई का शुक्र है। मुझे "सभी" को हटाने का कोई तरीका नहीं मिला। हर किसी ने कहा कि आपने इसे "लुकअप" फ़ंक्शन में छोड़ दिया है। वास्तव में आपको इसे "विकल्प" फ़ंक्शन में छोड़ना होगा – MagicLAMP

5

लघु और स्वच्छ समाधान। परिवर्तन सूची दृश्य पर क्लिक करते समय "ऑल" विकल्प के साथ अच्छा काम करता है।

def changelist_view(self, request, extra_context=None): 
     if not request.META['QUERY_STRING'] and \ 
      not request.META.get('HTTP_REFERER', '').startswith(request.build_absolute_uri()): 
      return HttpResponseRedirect(request.path + "?status__exact=1") 
     return super(YourModelAdmin,self).changelist_view(request, extra_context=extra_context) 
1

यहाँ glic3rinu के कोड के लिए मेरे अद्यतन (वहाँ टिप्पणी देखें) है, जो अजगर 3.4 और Django 1.9 पर काम करता है।7:

class DefaultFilterMixIn(admin.ModelAdmin): 
    def changelist_view(self, request, *args, **kwargs): 
     from django.http import HttpResponseRedirect 
     if self.default_filters: 
      #try: 
       test = request.META['HTTP_REFERER'].split(request.META['PATH_INFO']) 
       if test and test[-1] and not test[-1].startswith('?'): 
        url = reverse('admin:{}_{}_changelist'.format(self.opts.app_label, self.opts.model_name)) 
        filters = [] 
        for filter in self.default_filters: 
         key = filter.split('=')[0] 
         if not key in request.GET: 
          filters.append(filter) 
        if filters:      
         return HttpResponseRedirect("{}?{}".format(url, "&".join(filters))) 
      #except: pass 
     return super(DefaultFilterMixIn, self).changelist_view(request, *args, **kwargs)    
0

यहाँ एक डिफ़ॉल्ट फ़िल्टर व्यवस्थापक में सेट करने के लिए मेरे प्रयास (केवल Django 1.11 के साथ परीक्षण) है:

class ZeroCountListFilter(admin.SimpleListFilter): 
    title = _('include zero count') 
    parameter_name = 'count' 

    def choices(self, changelist): 
     yield { 
      'selected': self.value() is None or self.value() == 0, 
      'query_string': changelist.get_query_string({}, [self.parameter_name]), 
      'display': _('No'), 
     } 
     yield { 
      'selected': self.value() == '1', 
      'query_string': changelist.get_query_string({self.parameter_name: '1'}, []), 
      'display': _("Yes"), 
     } 

    def lookups(self, request, model_admin): 
     return (
      ('0', _('No')), 
      ('1', _('Yes')), 
     ) 

    def queryset(self, request, queryset): 
     if self.value() is None or self.value() == '0': 
      return queryset.exclude(count=0) 
     else: 
      return queryset 

चाल self.value() is None जाँच करने के लिए डिफ़ॉल्ट व्यवहार

संबंधित मुद्दे