Django व्यवस्थापक में एक ही मॉडल के लिए कई ModelAdmins / विचार


150

मैं एक ही मॉडल के लिए एक से अधिक ModelAdmin कैसे बना सकता हूं, प्रत्येक को अलग-अलग रूप से अनुकूलित किया गया है और विभिन्न URL से लिंक किया गया है?

मान लीजिए कि मेरे पास एक Django मॉडल है जिसे पोस्ट कहा जाता है। डिफ़ॉल्ट रूप से, इस मॉडल का व्यवस्थापक दृश्य सभी पोस्ट ऑब्जेक्ट को सूचीबद्ध करेगा।

मुझे पता है कि मैं पृष्ठ पर प्रदर्शित वस्तुओं की सूची को विभिन्न तरीकों से सूचीबध्द कर सकता हूं जैसे कि सूची_डिसप्ले जैसे चर सेट करना या querysetअपने मॉडलएडामिन में विधि को ओवरराइड करना जैसे:

class MyPostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pub_date')

    def queryset(self, request):
        request_user = request.user
        return Post.objects.filter(author=request_user)

admin.site.register(MyPostAdmin, Post)

डिफ़ॉल्ट रूप से, यह URL पर सुलभ होगा /admin/myapp/post। हालाँकि मैं एक ही मॉडल के कई विचार / ModelAdmins रखना चाहूंगा। उदाहरण के /admin/myapp/postलिए सभी पोस्ट ऑब्जेक्ट /admin/myapp/mypostsको सूचीबद्ध करेगा , और उपयोगकर्ता से संबंधित सभी पोस्ट को सूचीबद्ध करेगा , और उन सभी पोस्ट को /admin/myapp/draftpostसूचीबद्ध कर सकता है जो अभी तक प्रकाशित नहीं हुए हैं। (ये सिर्फ उदाहरण हैं, मेरा वास्तविक उपयोग-मामला अधिक जटिल है)

आप एक ही मॉडल (एक AlreadyRegisteredअपवाद में यह परिणाम ) के लिए एक से अधिक ModelAdmin पंजीकृत नहीं कर सकते । आदर्श रूप में मैं एक एकल ModelAdmin वर्ग में सब कुछ डाले बिना और URL के आधार पर एक अलग क्वेरीसेट वापस करने के लिए अपना 'urls' फ़ंक्शन लिखने के बिना इसे प्राप्त करना चाहूंगा ।

मैं Django स्रोत पर एक नज़र है और मुझे लगता है ModelAdmin.changelist_viewकि किसी तरह मेरे urls.py में शामिल किया जा सकता है जैसे कार्य देखते हैं , लेकिन मुझे यकीन नहीं है कि यह कैसे काम करेगा।

अद्यतन : मैंने जो चाहा है उसे करने का एक तरीका पाया है (नीचे देखें), लेकिन मैं अभी भी ऐसा करने के अन्य तरीके सुनना पसंद करूंगा।

जवाबों:


275

मुझे इस बात को प्राप्त करने का एक तरीका मिल गया है कि मैं क्या चाहता हूं, प्रॉक्सी मॉडल का उपयोग करके इस तथ्य को प्राप्त करने के लिए कि प्रत्येक मॉडल को केवल एक बार पंजीकृत किया जा सकता है।

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pubdate','user')

class MyPost(Post):
    class Meta:
        proxy = True

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)


admin.site.register(Post, PostAdmin)
admin.site.register(MyPost, MyPostAdmin)

तब डिफ़ॉल्ट PostAdminपर पहुंच होगी /admin/myapp/postऔर उपयोगकर्ता के स्वामित्व वाले पदों की सूची होगी /admin/myapp/myposts

Http://code.djangoproject.com/wiki/DynamicModels को देखने के बाद , मैं निम्न कार्य उपयोगिता फ़ंक्शन के साथ एक ही काम करने के लिए आया हूं:

def create_modeladmin(modeladmin, model, name = None):
    class  Meta:
        proxy = True
        app_label = model._meta.app_label

    attrs = {'__module__': '', 'Meta': Meta}

    newmodel = type(name, (model,), attrs)

    admin.site.register(newmodel, modeladmin)
    return modeladmin

इसका उपयोग इस प्रकार किया जा सकता है:

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)

create_modeladmin(MyPostAdmin, name='my-posts', model=Post)

8
यह कमाल का है। मुझे नहीं पता था कि एक प्रॉक्सी मॉडल को व्यवस्थापक साइट में पंजीकृत किया जा सकता है। यह वास्तव में मेरी बहुत मदद करेगा।
ब्रैंडन हेनरी

8
मुझे एक ही मॉडल को दो बार django व्यवस्थापक में पंजीकृत करने की आवश्यकता थी और प्रॉक्सी मॉडल काम करने लगते हैं। लेकिन मुझे अनुमति प्रणाली के साथ एक समस्या मिली। यहां देखें: code.djangoproject.com/ticket/11154
bjunix

4
ModelAdmin क्वेरीसेट के बजाय डिफ़ॉल्ट प्रबंधक को बदलने के लिए भी यह एक अच्छा विचार है। तो प्रॉक्सी मॉडल का व्यवहार व्यवस्थापक के बाहर भी सुसंगत है।
बोजनिक्स

4
अब असली जवाब यह है कि django ने आपको एक ही मॉडल के लिए दो एडमिन क्यों नहीं दिए? हमें केवल 2 लाइनों के लिए चीजों को हैक करने की आवश्यकता नहीं होनी चाहिए जो जांचता है और एक त्रुटि फेंकता है: s। महान जवाब अभी भी!
हस्सेक

1
@zzart: एक लंबित पुल अनुरोध है, जो केवल लापता डॉक्स प्रतीत होता है: github.com/django/django/pull/146/files
blueyed

3

पॉल स्टोन का जवाब बिल्कुल शानदार है! सिर्फ जोड़ने के लिए, Django 1.4.5 के लिए मुझे अपने कस्टम वर्ग से वारिस करने की आवश्यकता थीadmin.ModelAdmin

class MyPostAdmin(admin.ModelAdmin):
    def queryset(self, request):
        return self.model.objects.filter(id=1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.