2010-02-08 16 views
115

¿Cómo puedo crear más de un ModelAdmin para el mismo modelo, cada uno personalizado de manera diferente y vinculado a diferentes URL?Modelo múltipleAdmins/views para el mismo modelo en Django admin

Digamos que tengo un modelo de Django llamado Publicaciones. Por defecto, la vista de administración de este modelo listará todos los objetos Post.

Sé que puedo personalizar la lista de objetos que se muestran en la página de varias maneras mediante el establecimiento de variables como list_display o reemplazando el método queryset en mi ModelAdmin así:

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) 

Por defecto, esta sería accesible en la URL /admin/myapp/post. Sin embargo, me gustaría tener vistas múltiples/ModelAdmins del mismo modelo. Por ejemplo, /admin/myapp/post enumeraría todos los objetos de publicación y /admin/myapp/myposts mostraría todas las publicaciones que pertenecen al usuario, y /admin/myapp/draftpost podría enumerar todas las publicaciones que aún no se han publicado. (estos son solo ejemplos, mi caso de uso real es más complejo)

No se puede registrar más de un ModelAdmin para el mismo modelo (esto da como resultado una excepción AlreadyRegistered). Idealmente me gustaría lograr esto sin poniendo todo en una sola clase ModelAdmin y escribiendo mi propia función 'urls' para devolver un queryset diferente dependiendo de la URL.

He echado un vistazo a la fuente de Django y veo funciones como ModelAdmin.changelist_view que podrían incluirse de alguna manera en mi urls.py, pero no estoy seguro de cómo funcionaría.

Actualización: He encontrado una forma de hacer lo que quiero (ver más abajo), pero aún me gustaría escuchar otras formas de hacerlo.

Respuesta

214

he encontrado una manera de lograr lo que quiero, mediante el uso de modelos de proxy para moverse por el hecho de que cada modelo puede registrarse sólo una vez.

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) 

Entonces el PostAdmin por defecto sería accesible en/admin/miaplicacion/post y la relación de puestos pertenecientes al usuario estaría en/admin/miaplicacion/myposts.

Después de mirar http://code.djangoproject.com/wiki/DynamicModels, se me ha ocurrido con la siguiente función de utilidad función para hacer la misma 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 

Esto se puede utilizar de la siguiente manera:

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

esto es asombroso. No sabía que un modelo de proxy podía registrarse en el sitio de administración. esto realmente me ayudará mucho. –

+7

También necesitaba registrar los mismos modelos dos veces en django admin y los modelos de proxy parecen funcionar. Pero encontré un problema con el sistema de permisos. Vea aquí: http://code.djangoproject.com/ticket/11154 – bjunix

+4

También es una buena idea cambiar el administrador predeterminado en lugar del conjunto de consulta ModelAdmin. Entonces el comportamiento del modelo proxy es consistente incluso fuera del administrador. – bjunix

1

solo use un list_filter o date_hierarchy.

date_hierarchy = 'pub_date' 

list_filter = ['pub_date',] 
+0

"Eso suma de navegación jerárquica, por fecha, a la parte superior de la página de la lista de cambios. A nivel superior, que muestra todos los disponibles años. Luego se reduce a meses y, finalmente, días ". de django docs –

+0

El filtrado por fecha fue solo un ejemplo, como dije en mi pregunta. De hecho, necesito hacer una consulta más compleja. –

+1

bien, entonces ¿cuáles son las preguntas? –

3

Paul Stone respuesta es absolutamente genial! Sólo para añadir, por Django 1.4.5 necesitaba para heredar mi clase personalizada de admin.ModelAdmin

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