2010-01-31 13 views
12

¿Hay alguna forma de extender otra aplicación ModelAdmin?Django: ¿se extienden otras aplicaciones ModelAdmin?

Tengo un proyecto que usa la funcionalidad ofrecida por django.contrib.comments.

clase El CommentsAdmin ModelAdmin tiene:
actions = ["flag_comments", "approve_comments", "remove_comments"]

me gustaría extender el CommentsAdmin ModelAdmin en mi proyecto para incluir una acción ban_user.

He intentado crear mi propio objeto NewCommentsAdmin(CommentsAdmin) en mi archivo admin.py y registrarlo, pero recibo un aviso 'AlreadyRegistered at /admin/' 'The model Comment is already registered'.

class NewCommentAdmin(CommentAdmin): 
    actions = ['ban_user'] 

    def ban_user(self, request, queryset): 
     pass 

admin.site.register(Comment, NewCommentAdmin) 

¿Hay una manera de hacer esto sin modificar el código django.contrib.comments original?

Respuesta

3

supongo que hay algo como esto en la parte superior de su archivo:

from django.contrib.comments.admin import CommentAdmin 

Esta importación ejecuta el registro del modelo (en la parte inferior de este archivo admin) nuevo.

Una idea que no se ve muy bonito (que en realidad no lo he probado) podría ser:

from django.contrib.comments.models import Comment 
from django.contrib import admin 
from django.contrib.admin.sites import NotRegistered 

# Try to unregister the Comment model 
# that was registered via the auto_discover method 
try: 
    admin.site.unregister(Comment) 
except NotRegistered: 
    pass 

# Now we can load the CommentAdmin (which reregisters the admin model) 
from django.contrib.comments.admin import CommentAdmin 

# We have to unregister again: 
try: 
    admin.site.unregister(Comment) 
except NotRegistered: 
    pass 

# Now your stuff... 

supongo que esto se podría hacer mejor, pero debería funcionar. Para que este enfoque funcione, la aplicación que contiene este archivo debe estar después de la aplicación de comentarios en INSTALLED_APPS.

Ahora a su clase. Creo que si escribes actions = ['ban_user'] realmente sobrescribes todas las acciones en la clase principal. Creo que es la forma más fácil de anular el get_actions método:

class NewCommentAdmin(CommentAdmin): 

    def get_actions(self, request): 
     actions = super(NewCommentAdmin, self).get_actions(request) 

     # Do some logic here based on request.user if you want 
     # to restrict the new action to certain users 
     actions.append('ban_user') 

     return actions 

    def ban_user(self, request, queryset): 
     pass 

admin.site.register(Comment, NewCommentAdmin) 

Espero que ayude (o al menos da una idea) :)

+0

Um, esto es mucho más complicado de lo necesario. Simplemente importe CommentAdmin, subclasselo, elimine el registro una vez, y registre su versión. –

+0

@Carl Meyer: ¿Estás seguro? Intenté que el widget del mapa de Geodjango funcionara en la interfaz. Para eso, necesitaba importar mi AdminModel personalizado definido en mi archivo 'admin.py'. Cuando importo esta clase, la función 'admin.site.register' se ejecutó de nuevo. Ese es mi punto. Cuando intenta importar la clase, intenta registrar el modelo nuevamente.¿Lo conseguiste trabajando con éxito? Si hay otra solución, estoy más que complacido aquí. –

+0

El código de nivel de módulo solo se ejecuta dos veces si el módulo se importa a través de dos rutas diferentes. En general, esto no debería suceder. No sé si GeoDjango hace algo funky, nunca lo usó. Vea mi respuesta para la versión simple que tengo trabajando en producción. –

9

Así es como lo hago en un proyecto para el modelo del usuario. En el admin.py para mi aplicación:

from django.contrib import admin 
from django.contrib.auth.admin import UserAdmin 
from django.contrib.auth.models import User 

class MyUserAdmin(UserAdmin): 
    # ... 

admin.site.unregister(User) 
admin.site.register(User, MyUserAdmin) 
0

Tenga una mirada en https://github.com/kux/django-admin-extend

ofrece algunas funciones fáciles de usar y decoradores que implementan la funcionalidad que está solicitando de manera muy flexible. La documentación hace un buen trabajo al explicar por qué usar este enfoque es mejor que la herencia directa.

También tiene soporte para inyectar campos bidireccionales en muchos campos.

Cuestiones relacionadas