Pregunta

Recientemente he comenzado a usar Django para administrar una gran aplicación existente que fue cultivado orgánicamente lo largo de los años usando twisted.web. Me comenzó a experimentar con Django y es la interfaz de administración automática y he estado muy satisfechos con los resultados.

Una cosa que parece que falta para mis propósitos es la capacidad de ofrecer a los usuarios acceso de sólo lectura a los datos. Por ejemplo tenemos un papel donde las personas se les permite entrar al sistema y crear órdenes de compra. Ellos también tienen que ser capaces de ver, pero no editar otros datos de clientes o productos.

¿Cómo puedo crear permisos "Ver" en la administración de Django para que los usuarios pueden modificar los datos de algunas tablas, si bien tienen acceso de sólo lectura a los demás?

Actualización: Django administración parece dame la CUD de una interfaz CRUD. ¿Cómo consigo la parte de sólo lectura con los permisos y los grupos asociados?

Actualización 2010-Feb-12: de sólo lectura Django 1.2 incluirá ahora. Datos a continuación.


respondí a mi propia pregunta supongo. Al mover el contenido a una respuesta real a continuación.

¿Fue útil?

Solución 5

La posibilidad de añadir campos de sólo lectura a la vista de administración se incluye ahora en la versión 1.2 de Django.

Vea el número del billete 342 http://code.djangoproject.com/ticket/342

Vea el número de cambios 11965 http://code.djangoproject.com/changeset/11965

Consulte la documentación http: //docs.djangoproject .com / es / dev / ref / contrib / admin / # django.contrib.admin.ModelAdmin.readonly_fields

Otros consejos

Esta es la forma en que cambié Django 1.0.2 para agregar permisos 'Ver'. En este momento no hay disponible diff.

[X] 'vista' por defecto 1. Agregado lista de permisos

#./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. Ensayo se añade el permiso 'vista' a todos los modelos

run manage.py syncdb

Me confirmó que el permiso de visualización se añade ahora para todas las tablas en la tabla auth_permissions

[X] 3. Agregar "get_view_permission" por defecto clase del modelo.

get_view_permission Añadido a la clase del modelo. Usted puede encontrar esto en el archivo ./db/models/options.py Esto es utilizado por la clase admin en el siguiente paso.

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

[X] 4. Agregar "has_view_permission" a los valores de la clase de administración

Para ser coherentes Voy a añadir "has_view_permission" al sistema. Parece que debería estar en algún lugar de contrib / admin / options.py . Se aseguró de si el usuario tiene permiso de cambio ha, a continuación, ver los permisos están implicados de forma automática.

# /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] plantilla por defecto 5. Actualización de la lista de modelos si el usuario tiene permiso de visualización

He modificado la plantilla predeterminada en contrib / admin / templates / admin / index.html. Esto también podría ser manejado por copiar el archivo en el directorio de plantillas locales en su lugar. Hice cambios tanto así que tengo una copia si una actualización posterior sobrescribe mis cambios.

 {% 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. Confirmar usuario puede "vista", pero no "cambio" el modelo

Encontrados contrib / admin / templatetags / admin_modify.py parece controlar salvar / guardar y continuar botones que aparecen o no. Cambiado "salvar" campo del fallo de siempre verdad, para comprobar si el contexto y permisos. El usuario debe ser capaz de ahorrar si tienen cambiar o añadir permisos.

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

[X] 7. Retire "Guardar y añadir otro" botón si usuario está viendo un artículo

Modificado contrib / admin / templatetags / admin_modify.py de nuevo. No sé lo que significa '' salvar_como así que tal vez se rompió algo, pero parece que funciona.

    #'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. Modificar "vista" permiso para hacer formulario de lectura sólo

Si el usuario tiene permiso "vista" y el permiso "cambio", luego no hacer nada. Cambio anula la vista.

Si el usuario tiene permiso "vista" y sin "cambio" y luego cambiar los formularios predeterminados y añadir DISABLED o READONLY atributos a los elementos del formulario. No todos los navegadores soportan esto, pero para mis propósitos que pueden requerir que los usuarios utilicen la correcta. discapacitados / solo lectura de ejemplo

Se han encontrado que no todos los navegadores de honor "sólo lectura" por lo que establece algunos controles de sólo lectura, y otros para personas con discapacidad. Esto permite a los usuarios copiar los datos de los controles de texto si es necesario.

#/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 %}

Este fragmento hará superusuario el único que tiene acceso de escritura.

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

Es allí mismo, en el administrador. Puede establecer permisos de usuarios y grupos en el administrador añadir, modificar y borrar los modelos específicos.

Actualización: Lo sentimos, no he entendido bien la pregunta porque Malinterpreté la vista palabra para darle el Django es decir, en lugar de "sólo lectura". Si quieres sólo lectura utilizando el administrador, pienso que usted tiene que hacer un poco de trabajo. Ver este hilo, donde James Bennett (comunicado de Django gerente) dice:

  

Como se encontrará buscando en el   archivos de esta lista, esto no es   algo que la interfaz de administración de Django   está diseñado para soportar, por lo que cualquier   solución tendrá que venir en su totalidad   de usted escribir su propio código.

y

  

La administración de Django funciona en tres   Permisos: "add", "cambio" y   "Eliminar". No hay un "punto de vista, sino que   no hay modificaciones" permiso, por lo tanto   no hay manera de aplicar tal   restricción significativa sin hacer   codificación personalizada.

El trabajo adicional implicará que la adición de un "sólo lectura" permiso para ciertos modelos, y el cambio de las plantillas básicas de administración para comprobar si el usuario tiene ese permiso - y si es así, la desactivación de ciertos controles (tales como guardar los botones) y hacer que los demás solo lectura. Eso evitará retoques ocasionales, pero también puede que tenga que modificar la lógica del lado del servidor para comprobar el mismo permiso, para evitar los mensajes hechos de una manera disimulada para eludir los permisos.

Se puede crear un permiso de "sólo lectura" en su modelo y utilizando un código de jasuca con una modificación:

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

En el administrador de la aplicacion que tiene que dar el permiso de "cambio" y "sólo lectura" para el usuario.

Se pueden crear grupos en el módulo de autenticación. Luego, en admin.py inicio de sesión basado en grupo de usuarios, establecer el atributo de readonly_fields del modeladmin. Agregue el método has_add_permission def (auto, petición) para volver falsa para el grupo con permiso de sólo lectura. Dar al añadir, modificar permisos para el grupo. Ellos serán capaces de leer solamente los atributos de modelo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top