Django - Расширение еще одного приложения ModelAdmin? - PullRequest
14 голосов
/ 31 января 2010

Есть ли способ расширить другие приложения ModelAdmin?

У меня есть проект, который использует функциональность, предлагаемую django.contrib.comments.

Класс CommentsAdmin ModelAdmin имеет:
actions = ["flag_comments", "approve_comments", "remove_comments"]

Я бы хотел добавить в свой проект CommentsAdmin ModelAdmin действие ban_user.

.

Я попытался создать свой собственный объект NewCommentsAdmin(CommentsAdmin) в моем файле admin.py и зарегистрировать его, но я получил уведомление '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)

Есть ли способ сделать это без изменения исходного кода django.contrib.comments?

Ответы [ 4 ]

9 голосов
/ 31 января 2010

Вот как я это делаю в одном проекте для модели User. В admin.py для моего приложения:

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)
5 голосов
/ 31 января 2010

Отменить регистрацию модель Comment в первую очередь.

3 голосов
/ 31 января 2010

Я думаю, у вас есть что-то вроде этого в верхней части вашего файла:

from django.contrib.comments.admin import CommentAdmin

Этот импорт выполняет регистрацию модели (в самом низу этого админ-файла) снова .

Одна идея, которая выглядит не очень хорошо (я на самом деле не пробовал) может быть:

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...

Я думаю, это можно сделать лучше, но это должно сработать. Чтобы этот подход работал, приложение, содержащее этот файл, должно быть после приложения комментариев в INSTALLED_APPS.

Теперь к вашему классу. Я думаю, что если вы напишите actions = ['ban_user'], вы на самом деле перезапишите все действия в родительском классе. Я думаю, что это самый простой способ переопределить метод get_actions:

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)

Надеюсь, что это помогает (или, по крайней мере, дает представление):)

0 голосов
/ 15 января 2014

Посмотрите на https://github.com/kux/django-admin-extend

Он предлагает несколько простых в использовании функций и декораторов, которые очень гибко реализуют запрашиваемую вами функцию. Документация довольно хорошо объясняет, почему использование этого подхода лучше, чем прямое наследование.

Также имеется поддержка введения двунаправленного множества во многие поля.

...