2010-02-08 18 views
115

Aynı model için birden fazla ModelAdmin'i nasıl oluşturabilirim, her biri farklı şekilde farklı ve farklı URL'lere bağlı mı?Çoklu ModelAdmins/görünümler aynı modelde Django admin

Diyelim ki Mesajlar adlı bir Django modelim var. Varsayılan olarak, bu modelin yönetici görünümü tüm Mesaj nesnelerini listeler.

ben list_display gibi değişkenleri ayarlamak veya şöyle benim ModelAdmin içinde queryset yöntemi geçersiz kılarak çeşitli şekillerde sayfada görüntülenen nesnelerin listesini özelleştirebilirsiniz biliyorum: Varsayılan olarak

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) 

, bu erişilebilir olacaktır URL /admin/myapp/post adresinde. Ancak aynı modele ait birden çok görünüm/ModelAdmins'e sahip olmak istiyorum. /admin/myapp/post, tüm posta nesnelerini listeleyecek ve /admin/myapp/myposts, kullanıcıya ait tüm yayınları listeleyecek ve /admin/myapp/draftpost, henüz yayınlanmamış olan tüm yayınları listeleyebilir. (bunlar sadece örneklerdir, benim gerçek kullanım durumum daha karmaşıktır)

Aynı modele birden fazla ModelAdmin kaydedemezsiniz (bu sonuç bir AlreadyRegistered istisnası). İdeal olarak, no'lu bu 'u her şeyi tek bir ModelAdmin sınıfına sokmadan ve URL'ye bağlı olarak farklı bir sorgulama döndürmek için kendi 'urls' işlevlerimi yazmayı istiyorum.

Django kaynağına bir göz attım ve bir şekilde urls.py'de yer alan ModelAdmin.changelist_view gibi işlevler görüyorum, ancak bunun nasıl çalışacağından tam olarak emin değilim.

Güncelleştirme: İstediğimi yapmanın bir yolunu buldum (aşağıya bakın), ancak bunu yapmanın başka yollarını hala duymak isterim.

cevap

214

ben her modeli sadece bir kez kaydedilebilir olabileceğini gerçeği aşmanın vekil modelleri kullanılarak, istediğini elde etmek için bir yol buldum.

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

class MyPosts(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) 

Ardından varsayılan PostAdmin/yönetici/myapp/yazı ve yönetici/Uygulamam/MYPOSTS/olacağını kullanıcının sahip olduğu mesajların listesine ulaşılabilir olacaktır. aşağıdaki gibi

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 

Bu kullanılabilir::

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

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

Bu harika. Yönetici sitede bir proxy modelinin kayıtlı olabileceğinin farkında değildim. Bu aslında bana çok yardımcı olacak. –

+7

Aynı modelleri django yöneticisinde iki kez kaydetmem gerekiyor ve proxy modelleri çalışıyor gibi görünüyor. Ancak izin sistemi ile ilgili bir problem buldum. Ayrıca bkz: http://code.djangoproject.com/ticket/11154 – bjunix

+4

Ayrıca, ModelAdmin queryset yerine varsayılan yöneticiyi değiştirmek için iyi bir fikir. Bu nedenle, proxy modelinin davranışı, yöneticinin dışında bile tutarlı olur. – bjunix

1

sadece bir list_filter veya date_hierarchy kullanın.

date_hierarchy = 'pub_date' 

list_filter = ['pub_date',] 
+0

benim özel sınıf miras için gerekli Django 1.4.5, eklemek için "O değişim listesi sayfasının üstüne tarihe göre hiyerarşik navigasyon, ekler. Üst düzeyde, mevcut tüm görüntüler Yıllar sonra aylara ve en nihayetinde günlere iner. " django belgelerinden –

+0

Tarihe göre filtreleme, yalnızca kendi sorduğum soruda belirttiğim gibi bir örnekti. Aslında daha karmaşık bir sorguya ihtiyacım var. –

+1

tamam, sorgular nelerdir? –

3

Paul Taş cevabı

http://code.djangoproject.com/wiki/DynamicModels baktıktan sonra, ben de aynı şeyi yapmak için aşağıdaki fonksiyon fayda fonksiyonu ile geldim kesinlikle harika! Tıpkı admin.ModelAdmin

class MyPostAdmin(admin.ModelAdmin): 
    def queryset(self, request): 
     return self.model.objects.filter(id=1)