Разрешить удаление только нескольких экземпляров модели из администратора - PullRequest
1 голос
/ 27 января 2012

в администраторе модели, я хотел бы разрешить действие удаления только для некоторых экземпляров (моя модель имеет DateTimeField, и я хотел бы отключить действие удаления для экземпляров, для которых это поле установлено на текущий месяц) .

Кто-нибудь может помочь?

Спасибо

EDIT

Я попробовал метод, предложенный Крисом в его ответе ниже, но obj всегда равен None:

class UserProfileAdmin(admin.ModelAdmin):

    def has_delete_permission(self, request, obj=None):

        # obj is always None

        return super(UserProfileAdmin, self).has_delete_permission(request, obj=obj)

Ответы [ 2 ]

4 голосов
/ 27 января 2012
class MyModelAdmin(admin.ModelAdmin):
     ...
     def has_delete_permission(self, request, obj=None):
         if obj is not None and \
            obj.my_date_field.month == datetime.now().month and \
            obj.my_date_field.year == datetime.now().year:

             return False

         return super(MyModelAdmin, self).has_delete_permission(request, obj=obj)

UPDATE

Это не «всегда None», это установленный для конкретного объекта, когда конкретный объект может быть установлен. В списке изменений, и особенно в вашем сценарии, при попытке массового удаления из списка изменений он установлен на None, потому что ни один отдельный объект явно не может быть определен.

Если вам необходимо учесть удаление из списка изменений, вам придется создать собственное действие по удалению и заменить версию Django по умолчанию. Что-то вроде:

class MyModelAdmin(admin.ModelAdmin):
    ...
    actions = ['limited_delete_selected']

    # Need to remove the default delete_selected action
    def get_actions(self, request):
        actions = super(MyModelAdmin, self).get_actions(request)
        if actions.has_key('delete_selected'):
            del actions['delete_selected']
        return actions

    def limited_delete_selected(self, request, queryset):
        # filter selected items to only those that are actually deletable
        now = datetime.now()
        queryset = queryset.exclude(date_field__month=now.month, date_field__year=now.year)

        # call Django's delete_selected with limited queryset
        from django.contrib.admin.actions import delete_selected
        delete_selected(self, request, queryset)
    limited_delete_selected.short_description = "Delete selected objects or whatever you want it to say"

На самом деле вам понадобится как действие, так и исходный has_delete_permission, поскольку объекты могут быть удалены по отдельности в представлении change_form.

1 голос
/ 27 января 2012

Ознакомьтесь с документами по поводу переопределения встроенных методов модели: https://docs.djangoproject.com/en/1.3/topics/db/models/#overriding-model-methods

...