python - superuser - django shell




Multiple ModelAdmins/views per lo stesso modello nell'amministratore di Django (2)

Ho trovato un modo per ottenere ciò che voglio, usando i modelli proxy per aggirare il fatto che ogni modello può essere registrato solo una volta.

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)

Quindi il PostAdmin predefinito sarebbe accessibile a / admin / myapp / post e l'elenco di post di proprietà dell'utente sarebbe in / admin / myapp / myposts.

Dopo aver consultato http://code.djangoproject.com/wiki/DynamicModels , ho creato la seguente funzione di utilità di funzione per fare la stessa cosa:

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

Questo può essere usato come segue:

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

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

Come posso creare più di un ModelAdmin per lo stesso modello, ognuno personalizzato in modo diverso e collegato a URL diversi?

Diciamo che ho un modello Django chiamato Post. Per impostazione predefinita, la vista amministratore di questo modello elencherà tutti gli oggetti Post.

So che posso personalizzare l'elenco di oggetti visualizzati sulla pagina in vari modi impostando variabili come list_display o sovrascrivendo il metodo queryset nel mio ModelAdmin in questo modo:

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)

Per impostazione predefinita, questo sarebbe accessibile all'URL /admin/myapp/post . Tuttavia mi piacerebbe avere più viste / ModelAdmins dello stesso modello. ad esempio /admin/myapp/post elencherebbe tutti gli oggetti post e /admin/myapp/myposts elencherebbe tutti i post appartenenti all'utente, e /admin/myapp/draftpost potrebbe elencare tutti i post che non sono ancora stati pubblicati. (questi sono solo esempi, il mio caso d'uso effettivo è più complesso)

Non è possibile registrare più ModelAdmin per lo stesso modello (ciò si traduce in un'eccezione AlreadyRegistered ). Idealmente mi piacerebbe ottenere questo risultato senza mettere tutto in una singola classe ModelAdmin e scrivere la mia funzione 'urls' per restituire un queryset diverso a seconda dell'URL.

Ho dato un'occhiata al sorgente Django e vedo funzioni come ModelAdmin.changelist_view che potrebbero essere in qualche modo incluse nel mio urls.py, ma non sono sicuro di come funzionerebbe.

Aggiornamento : ho trovato un modo per fare ciò che voglio (vedi sotto), ma mi piacerebbe ancora sentire altri modi per farlo.


La risposta di Paul Stone è assolutamente fantastica! Giusto per aggiungere, per Django 1.4.5 avevo bisogno di ereditare la mia classe personalizzata da admin.ModelAdmin

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




django-admin