2011-10-07 17 views
8

मैं की तरह एक साधारण Django मॉडल है नहीं है:छनन Django व्यवस्थापक अशक्त/द्वारा अशक्त

class Person(models.Model): 
    referrer = models.ForeignKey('self', null=True) 
    ... 

इस मॉडल की ModelAdmin में, मैं इसे कैसे किया जाए या नहीं रेफरर रिक्त है द्वारा फ़िल्टर किया जा करने की अनुमति होगी? डिफ़ॉल्ट रूप से, list_filter में रेफरर जोड़ने से ड्रॉपडाउन को दिखाया जा सकता है कि प्रत्येक व्यक्ति रिकॉर्ड रिकॉर्ड करता है, जो सैकड़ों हजारों में हो सकता है, जो प्रभावी रूप से लोड होने से पृष्ठ को रोकता है। भले ही यह लोड हो, फिर भी मैं अपने इच्छित मानदंडों से फ़िल्टर नहीं कर सकता।

यानी मैं इसे कैसे संशोधित करूं ताकि ड्रॉपडाउन में केवल "सभी", "नल" या "नॉट नल" विकल्प सूचीबद्ध हों?

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

उत्तर

1

के साथ the top solution here के मिश्रण का उपयोग करके मैं समाप्त हुआ।

हालांकि, मुझे स्निपेट को थोड़ा सा ट्विक करना था, फ़ील्ड प्रकार प्रतिबंध को छोड़ना और नया फ़ील्ड_पैथ जोड़ना था, जिसे हाल ही में 1.3 में जोड़ा गया था।

from django.contrib.admin.filterspecs import FilterSpec 
from django.db import models 
from django.utils.safestring import mark_safe 
from django.utils.translation import ugettext as _ 

class NullFilterSpec(FilterSpec): 
    #fields = (models.CharField, models.IntegerField, models.FileField) 

    @classmethod 
    def test(cls, field): 
     #return field.null and isinstance(field, cls.fields) and not field._choices 
     return field.null and not field._choices 
    #test = classmethod(test) 

    def __init__(self, f, request, params, model, model_admin, field_path=None): 
     super(NullFilterSpec, self).__init__(f, request, params, model, model_admin, field_path) 
     self.lookup_kwarg = '%s__isnull' % f.name 
     self.lookup_val = request.GET.get(self.lookup_kwarg, None) 

    def choices(self, cl): 
     # bool(v) must be False for IS NOT NULL and True for IS NULL, but can only be a string 
     for k, v in ((_('All'), None), (_('Has value'), ''), (_('Omitted'), '1')): 
      yield { 
       'selected' : self.lookup_val == v, 
       'query_string' : cl.get_query_string({self.lookup_kwarg : v}), 
       'display' : k 
      } 

# Here, we insert the new FilterSpec at the first position, to be sure 
# it gets picked up before any other 
FilterSpec.filter_specs.insert(0, 
    # If the field has a `profilecountry_filter` attribute set to True 
    # the this FilterSpec will be used 
    (lambda f: getattr(f, 'isnull_filter', False), NullFilterSpec) 
) 
2

एक बेहतर स्पष्टीकरण वाला एक स्निपेट this हो सकता है। Django 1.4 simplified filter mechanism के साथ जहाज जाएगा।

1

4 साल (https://code.djangoproject.com/ticket/5833) के लिए इसके लिए एक टिकट उछाल रहा है। यह 1.3 मील का पत्थर चूक गया, लेकिन नई फीचर स्थिति तक पहुंच गया है और संभवत: यह ट्रंक में है। यदि आपको ट्रंक से चलने से कोई फर्क नहीं पड़ता है, तो आप इसका उपयोग कर सकते हैं। पैच माना जाता है कि 1.3 संगत है, हालांकि, आप संभवतः अपने वर्तमान इंस्टॉलेशन को पैच करने के साथ प्राप्त कर सकते हैं।

13

के बाद से Django 1.4 फिल्टर के लिए कुछ परिवर्तन लाता है, मैंने सोचा था कि मैं किसी समय मैं सिर्फ Django 1.4 RC1 के साथ काम करने Cerin के स्वीकार किए जाते हैं जवाब से कोड को संशोधित खर्च बचाने के लिए।

मेरे पास एक मॉडल है जिसमें "स्टार्ट" नामक टाइमफिल्ड (शून्य = ट्रू) है और मैं शून्य और गैर-शून्य मानों के लिए फ़िल्टर करना चाहता था, इसलिए यह ओपी के समान ही समस्या है।
तो, यहाँ क्या मेरे लिए काम किया है ...

परिभाषित किया जाता है (वास्तव में शामिल है) इन admin.py में:

class SomeModelAdmin(admin.ModelAdmin): 
    list_filter = (StartNullFilterSpec,) 
+3

1,4 में वहाँ '' BooleanFieldListFilter'' जो डिफ़ॉल्ट रूप से ऐसा करेगा। 'list_filter = (('myfield', BooleanFieldListFilter), 'other_field', 'other_field2')' '। गैर बुलियन फ़ील्ड में यह समान प्रभाव प्राप्त करता है जैसे शून्य/शून्य नहीं। –

+1

@KyleMacFarlane डेटटाइम फ़ील्ड के लिए काम नहीं करता है हालांकि – Kos

+1

1.6 का उपयोग करके ऐसा लगता है कि यह विदेशी के लिए काम नहीं करता है। –

7

मैं:

from django.contrib.admin.filters import SimpleListFilter 

class NullFilterSpec(SimpleListFilter): 
    title = u'' 

    parameter_name = u'' 

    def lookups(self, request, model_admin): 
     return (
      ('1', _('Has value'),), 
      ('0', _('None'),), 
     ) 

    def queryset(self, request, queryset): 
     kwargs = { 
     '%s'%self.parameter_name : None, 
     } 
     if self.value() == '0': 
      return queryset.filter(**kwargs) 
     if self.value() == '1': 
      return queryset.exclude(**kwargs) 
     return queryset 



class StartNullFilterSpec(NullFilterSpec): 
    title = u'Started' 
    parameter_name = u'started' 

से सिर्फ ModelAdmin में उन्हें इस्तेमाल किया फ्रेंहर के उत्तर का एक सरल संस्करण है, जो वास्तव में __isnull स्थिति पर फ़िल्टर करता है। (Django 1।4):

from django.contrib.admin import SimpleListFilter 

class NullListFilter(SimpleListFilter): 
    def lookups(self, request, model_admin): 
     return (
      ('1', 'Null',), 
      ('0', '!= Null',), 
     ) 

    def queryset(self, request, queryset): 
     if self.value() in ('0', '1'): 
      kwargs = { '{0}__isnull'.format(self.parameter_name) : self.value() == '1' } 
      return queryset.filter(**kwargs) 
     return queryset 
फिर भी

:

class StartNullListFilter(NullListFilter): 
    title = u'Started' 
    parameter_name = u'started' 

और अंत में:

class SomeModelAdmin(admin.ModelAdmin): 
    list_filter = (StartNullListFilter,) 

मैं व्यक्तिगत रूप से कक्षाओं के दर्जनों के साथ मेरी admin.py कचरा करना पसंद नहीं है, तो मैं आया इस तरह के एक सहायक समारोह के साथ:

def null_filter(field, title_=None): 
    class NullListFieldFilter(NullListFilter): 
     parameter_name = field 
     title = title_ or parameter_name 
    return NullListFieldFilter 

कौन सा मैं बाद में आवेदन कर सकते हैं के रूप में:

class RefererFilter(admin.SimpleListFilter): 
    title = 'has referer' 
    # Parameter for the filter that will be used in the URL query. 
    parameter_name = 'referer__isnull' 

    def lookups(self, request, model_admin): 
     return (
      ('False', 'has referer'), 
      ('True', 'has no referer'), 
     ) 

    def queryset(self, request, queryset): 
     if self.value() == 'False': 
      return queryset.filter(referer__isnull=False) 
     if self.value() == 'True': 
      return queryset.filter(referer__isnull=True) 

तो बस उन्हें ModelAdmin में इस्तेमाल किया:

class OtherModelAdmin(admin.ModelAdmin): 
    list_filter = (null_filter('somefield'), null_filter('ugly_field', _('Beautiful Name')),) 
2

वहाँ एक आसान तरीका है

class PersonAdmin(admin.ModelAdmin): 
    list_filter = (RefererFilter,) 
संबंधित मुद्दे