2012-01-17 26 views
10

में एक कस्टम ऐप_सूची को परिभाषित करना मैं django के व्यवस्थापक अनुक्रमणिका पृष्ठ में उपयोग करने के लिए एक कस्टम एप्लिकेशन सूची को परिभाषित करना चाहता हूं क्योंकि मैं डिफ़ॉल्ट वर्णमाला क्रम के बजाय ऐप्स को एक विशिष्ट क्रम में प्रदर्शित करना चाहता हूं। विभिन्न एसओ पदों के माध्यम से ट्रैवलिंग यह दिखाई देगी कि किसी भी स्पष्ट स्थानों (जैसे admin.py, models.py) में इच्छित एप्लिकेशन ऑर्डर घोषित करना अभी तक संभव नहीं है।django व्यवस्थापक अनुक्रमणिका पृष्ठ

अब, मैं देख सकता हूँ कि Django व्यवस्थापक के index.html फ़ाइल निम्न कथन शामिल हैं:

{% for app in app_list %} 
    # do stuff with the app object 

तो मैं एक कस्टम सूची, जिसे कहते वस्तु का उपयोग करने के my_app_list इसे बदलने के लिए, चाहते हैं। अजगर में मैं निम्नलिखित लाइनों के साथ ऐसा करते हैं चाहते हैं: तो यह है

from django.db.models import get_app 
my_app_list = [get_app('myapp1'), get_app('myapp2'), ..., get_app('django.contrib.auth')] 
for app in my_app_list 
    ... 

मेरा प्रश्न, मैं कैसे पहले 2 लाइनों के बराबर ऊपर index.html फ़ाइल के अपने स्थानीय प्रतिलिपि में कोड करते हैं?

या, वैकल्पिक रूप से, मुझे कौन सी पायथन स्रोत फ़ाइल को उन पंक्तियों को सम्मिलित करना चाहिए ताकि परिवर्तनीय my_app_list index.html के भीतर उपलब्ध हो।

अग्रिम धन्यवाद।

फिल

+0

यह मेरे लिए ठीक काम करता है => http://djangosnippets.org/snippets/2613/ – Serafeim

+0

@Serafeim इसके लिए धन्यवाद। एक बार जब मैंने अपने सर्वर को अपग्रेड किए जाने के परिणामस्वरूप विभिन्न 32-बिट बनाम 64-बिट पायथन/डीजेंगो समस्याओं का समाधान किया है, तो मैं इसे एक बार दूंगा! – Phil

उत्तर

8

उपवर्ग django.contrib.admin.site.AdminSite().index() विधि ओवरराइड, और कुछ इस तरह करते हैं:

class MyAdminSite(django.contrib.admin.site.AdminSite): 
    def index(self, request, extra_context=None): 
     if extra_context is None: 
      extra_context = {} 
     extra_context["app_list"] = get_app_list_in_custom_order() 
     return super(MyAdminSite, self).index(request, extra_context) 

my_admin_site = MyAdminSite() के साथ इस उपवर्ग का एक उदाहरण इन्स्तांत, (सामान्य my_admin_site.register() का प्रयोग करके) यह करने के लिए अपने मॉडल देते हैं, और URLconf में अटैच कर; इससे हो जाना चाहिए।

+0

इस सुझाव के लिए धन्यवाद - अभी तक इसका परीक्षण करने का मौका नहीं मिला है। मेरे पास वापस रिपोर्ट करेगा। हालांकि एक व्यवहार्य विकल्प की तरह लग रहा है। – Phil

+1

आपके द्वारा सुझाए गए कोड खंड को समझ में आता है, लेकिन यह मुझे स्पष्ट नहीं है कि इसे कहाँ रहना चाहिए। मैंने इसे अपने अनुप्रयोगों में से एक के लिए admin.py मॉड्यूल के अंदर रखना शुरू कर दिया, लेकिन एहसास हुआ कि यह समझ में नहीं आता है क्योंकि यह कोड का एक साइट-व्यापी टुकड़ा है, और किसी विशेष एप्लिकेशन के लिए विशिष्ट नहीं है। साथ ही, मुझे यकीन नहीं था कि इस कोड का उपयोग करने के लिए यूआरएल कॉन्फ़िगर कैसे या क्यों संशोधित करेगा क्योंकि मैंने कोई यूआरएल नहीं बदला है। – Phil

+0

अंत में इस विधि को आजमाने के लिए गोल हो गया। दुर्भाग्य से मैं इसे काम नहीं कर सका। सबसे पहले, get_app() फ़ंक्शन index.html द्वारा अपेक्षित टूल ऑब्जेक्ट की बजाय मॉड्यूल ऑब्जेक्ट देता है (मुझे स्रोत पढ़ना चाहिए था!)। दूसरा, AdminSite के उप-वर्ग को तुरंत चालू करके, और उसके बाद अपने स्वयं के ऐप्स पंजीकृत करके, ऐसा लगता है कि आप अन्य ऐप्स (जैसे Auth) की दृश्यता खो देते हैं जो डिफ़ॉल्ट व्यवस्थापक साइट ऑब्जेक्ट के विरुद्ध पंजीकृत हैं। इसलिए मुझे चीजों को कॉन्फ़िगर करने का कोई तरीका नहीं मिला, जैसे कि डिफ़ॉल्ट इंडेक्स और आपके स्वयं के ऐप्स व्यवस्थापक इंडेक्स व्यू में एक साथ दिखाई देते हैं। – Phil

0

(मैं इस, मैं AdminSite स्रोत के अपने पढ़ने पर यह आधारित कर रहा हूँ। प्रयास नहीं किया है) क्या @AdminKG कहा admin निर्देशिका कि आप की आवश्यकता की जड़ तक index.html फाइल कॉपी करने के बाद templates निर्देशिका के अंदर बनाने के लिए आपने setting.py पर घोषित किया है।

यदि आपके पास app_list के लिए एक स्पष्ट सॉर्टिंग तर्क है तो आप इसे अपने AdminSite के सबक्लास के .index() विधि में कार्यान्वित कर सकते हैं। अन्यथा आपको index.html पर ऐप सूची को हार्ड कोड करने की आवश्यकता होगी।

बस, अपने संदर्भ में यह है कि जैसे कुछ अपने खाके में कुछ पहुंचने के लिए:

def index(self, request, extra_context=None): 
    context = { 
     'app1':get_app('myappname'), 
     'app2': get_app('mysecondappname'), 
     # ... 
    } 
    context.update(extra_context or {}) 
    context_instance = template.RequestContext(request, current_app=self.name) 
    return render_to_response(self.index_template or 'admin/terminal_index.html', context, 
     context_instance=context_instance 
    ) 

अब वस्तुओं पर उपयोग करने के लिए उपलब्ध हैं ऐप्स को आपके index.htm

+0

"अन्यथा आपको index.html पर ऐप सूची को हार्ड कोड करने की आवश्यकता होगी।" दरअसल, यह मेरे प्रश्न की प्रकृति है। मैं अपने स्थानीय index.html फ़ाइल में, एक ऐप ऑब्जेक्ट के लिए एक हैंडल कैसे प्राप्त करूं, जिसके बारे में मुझे केवल इसका नाम पता है। मैं पायथन कोड में get_app ('myappname') फ़ंक्शन का उपयोग कर सकता हूं। क्या django की templating भाषा में एक समकक्ष कार्य है? शायद मैं पूरी तरह से गलत पेड़ भड़क रहा हूँ! – Phil

+0

@ फिल मैंने जवाब अपडेट किया – tikider

2

आप उपयोग करना कोई आपत्ति नहीं है django.contrib.admin.site.AdminSite() का उप-वर्ग, जब आपको customize your admin site की आवश्यकता होती है, तो मुझे लगता है कि व्युत्पन्न कक्षा में "अनुक्रमणिका" और "app_index" विधियों को फिर से लिखना एक व्यवहार्य विचार है। आप दो शब्दकोशों का उपयोग करके कस्टम ऑर्डरिंग कर सकते हैं जो सेटिंग.py में ऐप घोषणापत्र आदेश और मॉडल के पंजीकरण आदेश को संग्रहीत करते हैं। फिर 'name' के बावजूद इस क्षेत्र द्वारा ऐप_लिस्ट और ऑर्डर में एक कस्टम ऑर्डर फ़ील्ड्स ('order') जोड़कर, मूल AdminSite().index() और app_index() के कोड को फिर से लिखें।यह कोड है app_index() को छोड़कर, कि index() समारोह के समान है:

class MyAdminSite(AdminSite): 

    def __init__(self, name='admin', app_name='admin'): 
     super(MyAdminSite, self).__init__(name, app_name) 

     # Model's registration ordering. It's not necessary to 
     # categorize by app. 
     self._registry_ord = {} 

     # App ordering determined by declaration 
     self._app_ord = { 'auth' : 0 } 
     app_position = 1 
     for app in settings.INSTALLED_APPS: 
      self._app_ord[app] = app_position 
      app_position += 1 

    def register(self, model_or_iterable, admin_class=None, **options): 
     super(MyAdminSite, self).register(model_or_iterable, admin_class, **options) 

     if isinstance(model_or_iterable, ModelBase): 
      model_or_iterable = [model_or_iterable] 
     for model in model_or_iterable: 
      if model in self._registry: 
       if self._registry_ord: 
        self._registry_ord[model._meta.object_name] = max(self._registry_ord.values()) + 1 
       else: 
        self._registry_ord[model._meta.object_name] = 1 

    @never_cache 
    def index(self, request, extra_context=None): 
     """ 
     Displays the main admin index page, which lists all of the installed 
     apps that have been registered in this site. 
     """ 
     app_dict = {} 
     user = request.user 
     for model, model_admin in self._registry.items(): 
      app_label = model._meta.app_label 
      has_module_perms = user.has_module_perms(app_label) 

      if has_module_perms: 
       perms = model_admin.get_model_perms(request) 

       # Check whether user has any perm for this module. 
       # If so, add the module to the model_list. 
       if True in perms.values(): 
        info = (app_label, model._meta.module_name) 
        model_dict = { 
         'name': capfirst(model._meta.verbose_name_plural), 
         'perms': perms, 
         'order': self._registry_ord[model._meta.object_name] 
        } 
        if perms.get('change', False): 
         try: 
          model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=self.name) 
         except NoReverseMatch: 
          pass 
        if perms.get('add', False): 
         try: 
          model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=self.name) 
         except NoReverseMatch: 
          pass 
        if app_label in app_dict: 
         app_dict[app_label]['models'].append(model_dict) 
        else: 
         app_dict[app_label] = { 
          'name': app_label.title(), 
          'app_url': reverse('admin:app_list', kwargs={'app_label': app_label}, current_app=self.name), 
          'has_module_perms': has_module_perms, 
          'models': [model_dict], 
          'order': self._app_ord[app_label], 
         } 

     # Sort the apps alphabetically. 
     app_list = app_dict.values() 
     app_list.sort(key=lambda x: x['order']) 

     # Sort the models alphabetically within each app. 
     for app in app_list: 
      app['models'].sort(key=lambda x: x['order']) 

     context = { 
      'title': _('Site administration'), 
      'app_list': app_list, 
     } 
     context.update(extra_context or {}) 
     return TemplateResponse(request, [ 
      self.index_template or 'admin/index.html', 
     ], context, current_app=self.name) 

आप कस्टम AdminSite का उपयोग करते हैं और आप प्रमाणीकरण मॉडल आप शायद अपने कोड में यह कहीं जरूरत शामिल करना चाहते हैं (मैं इसे एक विशिष्ट में किए गए एप्लिकेशन extend user information करने के लिए:।

from django.contrib.auth.models import User, Group 
from myproject import admin 

admin.site.register(User) 
admin.site.register(Group) 
0

जब से तुम क्रम को लेकर चिंतित हैं, तुम मेरे समाधान उपयोगी पा सकते हैं
मूल रूप से, मैं एक फिल्टर है, जो शुरुआत करने के लिए app_list के वांछित तत्वों चाल बनाई

@register.filter 
def put_it_first(value, arg): 
    '''The filter shifts specified items in app_list to the top, 
    the syntax is: LIST_TO_PROCESS|put_it_first:"1st_item[;2nd_item...]" 
    ''' 
    def _cust_sort(x): 
     try: 
      return arg.index(x['name'].lower()) 
     except ValueError: 
      return dist 
    arg = arg.split(';') 
    arg = map(unicode.lower, arg) 
    dist = len(arg) + 1 
    value.sort(key=_cust_sort) 
    return value 

हालांकि, अगर आप उपयोग करें यदि आप कुछ तत्वों को हटाने की जरूरत कर सकते हैं:

@register.filter 
def remove_some(value, arg): 
    '''The filter removes specified items from app_list, 
    the syntax is: LIST_TO_PROCESS|remove_some:"1st_item[;2nd_item...]" 
    ''' 
    arg = arg.split(';') 
    arg = map(unicode.lower, arg) 
    return [v for v in value if v['name'].lower() not in arg] 

फिल्टर श्रृंखलित किया जा सकता है, तो आप एक ही समय में दोनों का उपयोग कर सकते हैं।
फ़िल्टरिंग फ़ंक्शंस उन तरीकों से नहीं लिखे गए हैं जो उन्हें गति राक्षस बनाते हैं, लेकिन यह टेम्पलेट परिभाषा द्वारा अक्सर प्रस्तुत नहीं किया जा रहा है।

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