Как я могу изменить Django для создания разрешения «просмотр»?

StackOverflow https://stackoverflow.com/questions/1336382

Вопрос

Недавно я начал использовать Django для управления большим существующим применением, которое было выращено органически на протяжении многих лет, используя Twisted.Web. Я начал экспериментировать с Django и его автоматическим интерфейсом администратора, и я был очень доволен результатами.

Одна вещь, которая, по -видимому, отсутствует для моих целей, - это возможность предоставлять пользователям доступ только доступ к данным. Например, у нас есть роль, в которой людям разрешено входить в систему и создавать заказы на покупку. Они также должны иметь возможность просматривать, но не редактировать другие данные клиента или продукт.

Как я бы создал разрешения «просмотреть» в администраторе Django, чтобы пользователи могли изменить данные для некоторых таблиц, при этом прочитав только доступ к другим?

Обновление: администратор Django, кажется, дает мне CUD интерфейса CRUD. Как получить только чтение только с соответствующими разрешениями и группами?

Обновление 2010-Феб-12: Django 1.2 теперь будет включать только для чтения. Подробности ниже.


Я ответил на свой собственный вопрос, я думаю. Перемещение контента до реального ответа ниже.

Это было полезно?

Решение 5

Возможность добавления полей только для чтения в представление администратора теперь включена в Django версию 1.2.

Смотрите билет № 342http://code.djangoproject.com/ticket/342

См. Набор изменений 11965http://code.djangoproject.com/changeset/11965

См. Документацияhttp://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.modeladmin.readonly_fields

Другие советы

Вот как я изменил Django 1.0.2, чтобы добавить разрешения «просмотреть». Извините, нет различий.

X] 1. Добавлен «Просмотр» в список разрешений по умолчанию

#./contrib/auth/management/__init__.py
def _get_all_permissions(opts):
    "Returns (codename, name) for all permissions in the given opts."
    perms = []
    for action in ('add', 'change', 'delete', 'view'):
        perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
    return perms + list(opts.permissions)

X] 2. Проверьте разрешение на «представление» во все модели

run manage.py syncdb

Я подтвердил, что разрешение на представление теперь добавлено для всех таблиц в таблице Auth_permissions

X] 3. Добавьте "get_view_permission" в класс модели по умолчанию.

Добавлено get_view_permission в класс модели. Вы можете найти это в файле ./db/models/options.py Это используется классом администратора на следующем шаге.

def get_view_permission(self):
    return 'view_%s' % self.object_name.lower()

X] 4. добавить "has_view_permission" в класс администратора по умолчанию

Просто чтобы быть последовательным, я собираюсь добавить в систему "has_view_permission". Похоже, это должно быть где -то в Contrib/admin/options.py. Анкет Убедитесь, что у пользователя есть разрешение на изменение, тогда разрешения на просмотр автоматически подразумевается.

# /contrib/admin/options.py
# Added has_view_permissions
def has_view_permission(self, request, obj=None):
    """
    Returns True if the given request has permission to change or view
    the given Django model instance.

    If `obj` is None, this should return True if the given request has
    permission to change *any* object of the given type.
    """
    opts = self.opts
    return self.has_change_permission(request, obj) or \
        request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())

# modified get_model_perms to include 'view' too.
# No idea where this may be used, but trying to stay consistent
def get_model_perms(self, request):
        """
        Returns a dict of all perms for this model. This dict has the keys
        ``add``, ``change``, and ``delete`` and ``view`` mapping to the True/False
        for each of those actions.
        """
        return {
            'add': self.has_add_permission(request),
            'change': self.has_change_permission(request),
            'delete': self.has_delete_permission(request),
            'view': self.has_view_permission(request),
        }

# modified response_add function to return the user to the mode list
# if they added a unit and have view rights
... 
    else:
        self.message_user(request, msg)

        # Figure out where to redirect. If the user has change permission,
        # redirect to the change-list page for this object. Otherwise,
        # redirect to the admin index.
        #if self.has_change_permission(request, None):
        if self.has_change_permission(request, None) or self.has_view_permission(request, None):
            post_url = '../'
        else:
            post_url = '../../../'
        return HttpResponseRedirect(post_url)

 # modified the change_view function so it becomes the details 
 # for users with view permission

    #if not self.has_change_permission(request, obj):
    if not (self.has_change_permission(request, obj) or (self.has_view_permission(request, obj) and not request.POST)):
        raise PermissionDenied


  # modified the changelist_view function so it shows the list of items
  # if you have view permissions
def changelist_view(self, request, extra_context=None):
    "The 'change list' admin view for this model."
    from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
    opts = self.model._meta
    app_label = opts.app_label
    #if not self.has_change_permission(request, None):
    if not (self.has_change_permission(request, None) or self.has_view_permission(request, None)):
        raise PermissionDenied

X] 5. Обновите шаблон по умолчанию для перечисления моделей, если у пользователя есть разрешение на просмотр

Я изменил шаблон по умолчанию в Contrib/Admin/Templates/Admin/Index.html. Это также может быть обработано путем копирования файла в каталог локальных шаблонов. Я внес изменения в обоих, поэтому у меня есть копия, если более позднее обновление перезаписывает мои изменения.

 {% for model in app.models %}
            <tr>
            {% if model.perms.change %}
                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
            {% else %}
                {% if model.perms.view %}
                    <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
                {% else %}
                    <th scope="row">{{ model.name }}</th>
                {% endif %}
            {% endif %}

X] 6. Подтвердите, что пользователь может «просматривать», но не «изменить» модель

Найдено CONPIB/ADMIP/TEMPLATETAGS/ADMIN_MODIFY.PY, кажется, управляет сохранением/Сохраните и продолжайте появляться кнопки или нет. Изменено поле «Сохранить» по умолчанию всегда верно, чтобы проверить контекст и разрешения. Пользователь должен иметь возможность сохранить, если у него есть изменение или добавить разрешения.

 'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])

X] 7. Удалите кнопку «Сохранить и добавить другую», если пользователь просматривает элемент

Модифицированный вклад/admin/templateTags/admin_modify.py снова. Я не знаю, что означает 'save_as', так что, возможно, я что -то сломал, но, похоже, это работает.

    #'show_save_and_add_another': context['has_add_permission'] and
    #                    not is_popup and (not save_as or context['add']) ,
    'show_save_and_add_another': not is_popup and
        (( change and context['has_change_permission']) or (context['add'] and context['has_add_permission']))
        and
        (not save_as or context['add']),

X] 8. Изменить разрешение «просмотр», чтобы сделать только чтение формы.

Если пользователь имеет разрешение «просмотреть» и разрешение «изменить», то ничего не делайте. Изменить переопределяет представление.

Если пользователь имеет разрешение «представить» без «изменения», измените формы по умолчанию и добавьте атрибуты отключенных или чтения к элементам формы. Не все браузеры поддерживают это, но для моих целей я могу потребовать, чтобы пользователи использовали правильный. Пример отключений / чтения

Обнаружил, что не все браузеры чтят «readonly», поэтому он устанавливает некоторые элементы управления для Readonly, другие отключены. Это позволяет пользователям копировать данные из управления текстом, если это необходимо.

#/django/contrib/admin/templates/admin/change_form.html

{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}

</div>
</form></div>
{% if has_view_permission and not has_change_permission %}
    <script type="text/javascript">
    jQuery('input:text').attr('readonly', 'readonly');
    jQuery('textarea').attr('readonly', 'readonly');
    jQuery('input:checkbox').attr('disabled', true);
    jQuery('select').attr('disabled', true);
    jQuery('.add-another').hide();
    </script>
{% endif %}

Этот фрагмент сделает суперпользователь единственным с доступом к записи.

class AdminOwn(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return self.readonly_fields
        #get all fields as readonly
        fields = [f.name for f in self.model._meta.fields]
        return fields

Это прямо в администраторе. Вы можете установить разрешения для пользователей и групп в администраторе для добавления, изменения и удаления конкретных моделей.

Обновлять: Извините, я неправильно понял вопрос, потому что я неверно истолковал слово, чтобы дать ему значение django, а не «только для чтения». Если вы хотите, чтобы только чтение использовал администратора, я думаю, что вам нужно сделать немного работы. Видеть эта ветка, где Джеймс Беннетт (менеджер по выпуску Django) говорит:

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

а также

Администратор Django работает по трем разрешениям: «добавить», «изменить» и «удалить». Нет «представления, но не вносит никаких изменений» разрешения, поэтому нет никакого способа применять такое ограничение без значительного пользовательского кодирования.

Дополнительная работа будет включать в себя добавление разрешения «чтения» для определенных моделей и изменение основных шаблонов администратора, чтобы проверить, есть ли у пользователя это разрешение - и если это так, отключение определенных элементов управления (например, кнопок сохранения) и заставления других только для чтения. Анкет Это предотвратит повседневную возиву, но вам также может потребоваться изменять логику на стороне сервера, чтобы проверить то же разрешение, чтобы избежать любых сообщений, сделанных хитрым способом обойти разрешения.

Вы можете создать разрешение «чтения» в своей модели и использовать код Jasuca с модификацией:

модели.py:

class MyModel(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=256, null=True, blank=True)

    class Meta:
        permissions = (
            ('readonly_mymodel','Readonly MyModel'),
        )

admin.py:

class MyModelAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        if not request.user.is_superuser and request.user.has_perm('mymodel.readonly_mymodel'):
            return [f.name for f in self.model._meta.fields]
        return self.readonly_fields

В администраторе привязки вы должны дать разрешение на «изменение» и «чтения» пользователю.

Вы можете создавать группы в модуле Auth. Затем в Admin.py на основе входа в группу пользователей установите атрибут ModelAdmin Readonly_fields. Добавьте метод def has_add_permission (self, запрос), чтобы вернуть False для группы с разрешения Readonly. Дайте добавить, изменить разрешения на группу. Они смогут читать только атрибуты модели.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top