Django व्यवस्थापक, एक मॉडल छिपाएँ


85

व्यवस्थापक साइट के रूट पृष्ठ पर जहां पंजीकृत मॉडल दिखाई देते हैं, मैं कई मॉडलों को छिपाना चाहता हूं जो कि Django व्यवस्थापक के लिए पंजीकृत हैं।

अगर मैं सीधे उन लोगों को अपंजीकृत करता हूं, तो मैं नए रिकॉर्ड जोड़ने में सक्षम नहीं हूं क्योंकि नए प्रतीक "+" के प्रसार को जोड़ते हैं।

यह कैसे किया जा सकता है ?

जवाबों:


123

X0nix के उत्तर के आधार पर मैंने कुछ प्रयोग किए। ऐसा लगता है कि get_model_permsindex.html से मॉडल को बाहर करने से एक खाली ताना लौटता है , जबकि अभी भी आपको सीधे इंस्टेंस संपादित करने की अनुमति है।

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        """
        Return empty perms dict thus hiding the model from admin index.
        """
        return {}

admin.site.register(MyModel, MyModelAdmin)

माना। केवल यह एक समस्या है जब मैं कोड नहीं बदलना चाहता। मेरा क्या मतलब है, मेरे पास एक आधार ऐप है जिसे मैं अन्य ऐप पर निर्भरता से साफ रखना चाहता हूं। मैं इन निर्भरताओं को एक व्युत्पन्न परियोजना-विशिष्ट ऐप में रखता हूं। अब मैं चाहता हूं कि एडमिन इंटरफ़ेस केवल व्युत्पन्न ऐप को दिखाए, न कि आधार ऐप को। Django को काम करने के लिए आधार ऐप को सेटिंग्स / INSTALLED_APPS में सूचीबद्ध करने की आवश्यकता है। जाहिर है, आधार ऐप को प्रदर्शित नहीं होना चाहिए, लेकिन साथ ही मैं इसे अनमॉडिफाइड और पुन: प्रयोज्य नहीं रखना चाहता हूं। यहां [देखें] ( स्टैक एक्सचेंज / प्रश्न / 13923968 /)।
स्वेन

6
एक छोटा रास्ता:get_model_perms = lambda self, req: {}
तिगरान साल्वे

2
क्या होगा अगर मैं एक मॉडल को एक निश्चित उपयोगकर्ता के रूप में छिपाना चाहता हूं?
अलिर्ज़ा सनेई

1
इस समाधान के साथ सावधान रहें - भले ही लिंक गायब हो, उपयोगकर्ता इस तरह से स्वयं वस्तु पर कूद सकता है: / व्यवस्थापक / मुख्य / टिप्पणी / 2333 / परिवर्तन /
अच्छा

32

Django 1.8 और इसके बाद के संस्करण के लिए

Django 1.8 के बाद से, ModelAdminएक नया तरीका बुलाया गया हैhas_module_permission() व्यवस्थापक सूचकांक में एक मॉडल प्रदर्शित करने के लिए जिम्मेदार है।

किसी मॉडल को एडमिन इंडेक्स से छिपाने के लिए, इस विधि को अपनी ModelAdminकक्षा में बनाएं और वापस लौटें False। उदाहरण:

class MyModelAdmin(admin.ModelAdmin):
    ...
    def has_module_permission(self, request):
        return False

दुर्भाग्य has_module_permissionसे पूरे ऐप को प्रभावित करता है न कि केवल एक मॉडल को। इसलिए इसे ऐप में एक मॉडल में जोड़ने से ऐप मॉडल सूची (/ व्यवस्थापक / app_label /) में 403 निषिद्ध हो जाता है। देखें Django / योगदान / व्यवस्थापक / sites.py
फेबियन

1
@ फैबियन मुझे लगता है कि यह एक बग है। मैंने इसे Django के IRC चैनल पर पूछा, और वहां के कुछ लोग इस बात से सहमत हैं कि यह व्यवहार अवांछित है।
ज़ायर

@Fabian एडमिन इंडेक्स पेज को अभी भी / एडमिन से लिंक मानता है / यह संभव है कि उस बग को कुछ इस तरह दरकिनार किया जाए return request.path!='/admin/'। दुर्भाग्य से यह ऐप मॉडल सूची में उन मॉडलों को फिर से जोड़ता है।
एक्प

मैंने इस बग के लिए यहां एक टिकट खोला था । यह यहां तय किया गया है । इसे अगले रिलीज में शामिल किया जाना चाहिए, उम्मीद है।
xyres

Django 1.11 में गहरी कड़ी अभी भी काम करती है लेकिन इकाई मुख्य व्यवस्थापक स्क्रीन पर सूचीबद्ध नहीं है
Csaba Toth

22

एक ही समस्या है, यहाँ क्या मैं के साथ आया था।

पिछले समाधान की तरह - django से अपने /admin/index.html पर index.html की प्रतिलिपि बनाएँ और इसे इस तरह संशोधित करें:

{% for model in app.models %}
    {% if not model.perms.list_hide %}
    <tr>
    ...
    </tr>
    {% endif %}
{% endfor %}

और ModelAdmin उपवर्ग बनाएँ:

class HiddenModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, *args, **kwargs):
        perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
        perms['list_hide'] = True
        return perms

अब HiddenModelAdmin उपवर्ग के साथ पंजीकृत कोई भी मॉडल व्यवस्थापक सूची में दिखाई नहीं देगा, लेकिन "प्लस" के माध्यम से उपलब्ध होगा:

class MyModelAdmin(HiddenModelAdmin):
    ...

admin.site.register(MyModel, MyModelAdmin)

1

बदसूरत समाधान: व्यवस्थापक इंडेक्स टेम्प्लेट को ओवरराइड करें अर्थात इंडेक्स कॉपी करें। django से अपने /admin/index.html पर कॉपी करें और कुछ इस तरह जोड़ें:

{% for for model in app.models %}
    {% ifnotequal model.name "NameOfModelToHide" %}
    ...

1

यह शीर्ष x0nix के उत्तर पर एक वैकल्पिक इमारत है, और केवल अगर आप खुश हैं कि पंक्तियों को jquery के साथ छिपा रहे हैं।

दूसरे भाग से चिपकाने वाली कॉपी जो मैंने पुन: उपयोग की है उसका उत्तर दें

class HiddenModelAdmin(admin.ModelAdmin):
def get_model_perms(self, *args, **kwargs):
    perms = admin.ModelAdmin.get_model_perms(self, *args, **kwargs)
    perms['list_hide'] = True
    return perms

class MyModelAdmin(HiddenModelAdmin):
...

admin.site.register(MyModel, MyModelAdmin)

फिर django-jquery स्थापित करें और फिर अपने /admin/index.htmlटेम्पलेट में निम्नलिखित ब्लॉक जोड़ें :

{% extends "admin:admin/index.html" %}

{% block extrahead %}
    <script type="text/javascript" src="{{ STATIC_URL }}js/jquery.js"></script>
    {% if app_list %}
      <script type="text/javascript">
        $(function(){
          {% for app in app_list %}
            {% for model in app.models %}
                {% if model.perms.list_hide %}
                    $('div.app-{{ app.app_label }}').find('tr.model-{{ model.object_name|lower }}').hide();
                {% endif %}
            {% endfor %}
          {% endfor %}
        });
     </script>
   {% endif %}
{% endblock %}

आपको पूरे टेम्पलेट को कॉपी करने की आवश्यकता नहीं है, बस इसे विस्तारित करें और extraheadब्लॉक को ओवरराइड करें । ऊपर काम करने के लिए आपको django-apptemplates की आवश्यकता होगी ।


0

Django 1.2 में नए स्टेटमेंट्स हैं, जिसका अर्थ है कि वांछित सुविधा केवल ओवरराइटिंग एडमिन / इंडेक्स। Html द्वारा प्राप्त की जा सकती है

{% if model.name not in "Name of hidden model; Name of other hidden model" %}
    ...
{% endif %}

यह एक बुरा समाधान है, क्योंकि यह बहु-भाषा प्रवेश के बारे में परवाह नहीं करता है। आप सभी समर्थित भाषाओं में निश्चित रूप से मॉडल के नाम जोड़ सकते हैं। यह एक अच्छा समाधान है क्योंकि यह कोर Django फ़ंक्शन के एक से अधिक पहलुओं को अधिलेखित नहीं करता है।

लेकिन कुछ भी बदलने से पहले, मुझे लगता है कि लोगों को इस बारे में सोचना चाहिए ...

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


0

मेरे पास रजिस्टर करने और छिपाने के लिए बहुत सारे मॉडल प्रवेश थे, यदि आप अधिक DRY समाधान चाहते हैं, तो यह मेरे लिए काम किया (Django 1.10, Python 3.5)

# admin.py

def register_hidden_models(*model_names):
    for m in model_names:
        ma = type(
            str(m)+'Admin',
            (admin.ModelAdmin,),
            {
                'get_model_perms': lambda self, request: {}
            })
        admin.site.register(m, ma)

register_hidden_models(MyModel1, MyModel2, MyModel3)

मुझे लगता है कि यदि आप इसे फिर से उपयोग करना चाहते हैं तो आप इसे एक उपयोगिता वर्ग में रोल कर सकते हैं।


0

Django 1.8.18 के रूप में , has_module_permission()अभी भी जारी है। तो, हमारे मामले में हम भी इस्तेमाल किया get_model_perms()। इसी तरह, हमें केवल विशिष्ट उपयोगकर्ता के लिए मॉडल को छिपाने की आवश्यकता है, लेकिन superuserइसके सूचकांक प्रविष्टि तक पहुंचने में सक्षम होना चाहिए।

class MyModelAdmin(admin.ModelAdmin):
    def get_model_perms(self, request):
        if not request.user.is_superuser:
            return {}
        return super(MyModelAdmin, self).get_model_perms(request)

admin.site.register(MyModel, MyModelAdmin)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.