Django Admin - отключить ссылку редактирования для конкретных экземпляров модели - PullRequest
0 голосов
/ 28 мая 2018

Я определил следующую модель:

class BankAccount(models.Model):
    iban = models.CharField(max_length=34)
    owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='owner')

И следующий ModelAdmin на admin.py:

class BankAccountAdmin(admin.ModelAdmin):
    list_display = ('iban', 'owner',)

    def has_change_permission(self, request, obj=None):
        return obj is None or obj.owner == request.user

Пока что администратор django разрешает пользователям редактировать только свой банковский счет., возвращая ошибку 403 Forbidden, когда у пользователя нет разрешения на изменение.

Проблема в том, что ссылка по-прежнему отображается для всех экземпляров BankAccount.

Есть идеи, как отключить ссылку для этих конкретных экземпляров в представлении администратора BankAccount?

1 Ответ

0 голосов
/ 28 мая 2018

Я наконец-то реализовал обходной путь для его решения на admin.py, как показано ниже.Комментарии объясняют добавленные строки.

from django.utils.html import format_html

class BankAccountAdmin(admin.ModelAdmin):
    list_display = ('iban_link', 'owner',)
    list_display_links = None  # The field displaying the link is given by iban_link()

    editable_objs = []  # This variable will store the instances that the logged in user can edit

    def has_change_permission(self, request, obj=None):
        return obj is None or obj.owner == request.user

    def iban_link(self, obj):
        # Shows the link only if obj is editable by the user. 
        if obj in self.editable_objs:
            return format_html("<a href='{id}'>{iban}</a>",
                               id=obj.id, iban=obj.iban,
                               )
        else:
            return format_html("{iban}",
                               id=obj.id, iban=obj.iban,
                               )

    # We make use of get_queryset method to fetch request.user and store the editable instances
    def get_queryset(self, request):
        # Stores all the BankAccount instances that the logged in user is owner of
        self.editable_objs = BankAccount.objects.filter(owner=request.user)
        return super(UserAdmin, self).get_queryset(request)

Обратите внимание, что без строки list_display_links = None ссылки все равно будут отображаться для всех экземпляров.Это связано с тем, что поведение по умолчанию отображает ссылки для всех экземпляров в первом столбце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...