2011-10-27 25 views
13

¿Hay alguna manera de hacer un modelo de solo lectura en django admin? pero me refiero a todo el modelo. Entonces, sin agregar, sin eliminar, sin cambiar, solo vea los objetos y los campos, todo como de solo lectura?Modelo completo como de solo lectura

+1

Parece un trabajo en progreso: https: // github.com/django/django/pull/5297 – Bosco

Respuesta

11

ModelAdmin ofrece los get_readonly_fields de gancho() - el siguiente se ha probado aún, mi idea era determinar todos los campos de la forma ModelAdmin lo hace, sin caer en una recursión con el sólo lectura propios campos:

from django.contrib.admin.util import flatten_fieldsets 

class ReadOnlyAdmin(ModelAdmin): 
    def get_readonly_fields(self, request, obj=None): 
     if self.declared_fieldsets: 
      fields = flatten_fieldsets(self.declared_fieldsets) 
     else: 
      form = self.get_formset(request, obj).form 
      fields = form.base_fields.keys() 
     return fields 

continuación subclase/Mezclar este administrador donde sea que deba ser un administrador de solo lectura.

Para añadir/eliminar y hacer que sus botones desaparecen, es probable que también quieren añadir

def has_add_permission(self, request): 
     # Nobody is allowed to add 
     return False 
    def has_delete_permission(self, request, obj=None): 
     # Nobody is allowed to delete 
     return False 

PS: En ModelAdmin, si has_change_permission (operaciones de búsqueda o su anulación) devuelve falso, usted don' Llegue a la vista de cambio de un objeto, y el enlace no se mostrará. En realidad sería genial si lo hiciera, y el get_readonly_fields() predeterminado verifica el permiso de cambio y establece todos los campos para que sean de solo lectura en ese caso, como en el caso anterior. De esa forma, los no cambiantes podrían al menos explorar los datos ... dado que la estructura de administración actual asume view = edit, como señala jathanism, esto probablemente requeriría la introducción de un permiso de "vista" además de agregar/cambiar/eliminar ...

EDIT: en relación con el establecimiento de todos los campos de sólo lectura, no probado pero mirando también prometedora:

readonly_fields = MyModel._meta.get_all_field_names() 

EDIT: Aquí hay otro

if self.declared_fieldsets: 
    return flatten_fieldsets(self.declared_fieldsets) 
else: 
    return list(set(
     [field.name for field in self.opts.local_fields] + 
     [field.name for field in self.opts.local_many_to_many] 
    )) 
+1

P.S .: Ahora he creado una solicitud de función a tal efecto https://code.djangoproject.com/ticket/17295 –

+1

Nota: método get_formset sólo está definido para InlineModelAdmin –

+0

Hola, gracias por esta compilación de opciones. Puede ser educado, aunque también proporcione los enlaces a las respuestas de las que obtienes las piezas, ya que veo que no son todas tuyas. Otra ventaja sería que los lectores también podrían ver los comentarios que otros hicieron sobre cada una de las sugerencias. – steps

2

Puede personalizar sus clases ModelAdmin con el atributo readonly_fields. Ver this answer para más.

+0

, pero ¿hay alguna manera de hacer que el modelo ** completo ** sea read_only, sin tener que agregar todos sus atributos a la lista readonly_fields? – juliomalegria

+1

Hay, pero no es fácil. Puede crear permisos personalizados en Django, pero cuando se trata del sitio de administración no es trivial. Django supone que si las personas pueden ver el contenido en la interfaz de administración, también pueden editarlo. Usted puede tratar de la sugerencia de [esta cuestión] (http://stackoverflow.com/questions/4334049/make-a-django-model-read-only) si se siente negrita. OMI es simplemente más fácil establecer explícitamente todos los campos de solo lectura y seguir adelante. – jathanism

0

que tenía un escenario similar en el que:

  1. usuario debe ser capaz de crear el modelo de objetos
  2. usuario debe ser capaz de ver la lista de objetos del modelo
  3. usuario should'nt poder editar un objeto, una vez que se ha creado

1 Anulación de la vista Cambiar

Dado que es posible anular change_view() en un ModelAdmin, podemos aprovechar eso para evitar la edición de instancias de modelo una vez que se han creado. Aquí hay un ejemplo que he usado:

def change_view(self, request, object_id, form_url='', extra_context=None): 
    messages.error(request, 'Sorry, but editing is NOT ALLOWED') 
    return redirect(request.META['HTTP_REFERER']) 

2.Condicionalmente Cambio Editar permisos

también me di cuenta de que los documentos de interpretar el resultado de ModelAdmin.has_change_permission() de diferentes maneras:

Should return True if editing obj is permitted, False otherwise. If obj is None, should return True or False to indicate whether editing of objects of this type is permitted in general (e.g., False will be interpreted as meaning that the current user is not permitted to edit any object of this type).

Significado pude comprobar si obj es None, en cuyo caso vuelvo True, de lo contrario vuelvo False , y esto en efecto permite a los usuarios ver la lista de cambios, pero no puede editar ni ver la forma_cambio una vez que se haya guardado la instancia del modelo.

def has_change_permission(self, request, obj = None, **kwargs): 
    if obj is None: 
     return True 
    else: 
     return False 

Aunque estoy pensando que esto también podría anular cualquier MODEL_can_change permisos permitiendo que los ojos no deseados de ver el cambio en la lista?

-1

De acuerdo con mi prueba de Django 1.8 no se puede utilizar después de los cual se indica en la respuesta # 3, pero funciona en Django 1.4:

##  self.get_formset(request, obj)  ## 
answer 3 needs fix. Generally, alternative codes for this issue about below section 
##   form = self.get_formset(request, obj).form ## 
##   fields = form.base_fields.keys()    ## 

puede ser algo como:

#~ (A) or 
[f.name for f in self.model._meta.fields] 

#~ (B) or 
MyModel._meta.get_all_field_names() 

#~ (C) 
list(set([field.name for field in self.opts.local_fields] + 
         [field.name for field in self.opts.local_many_to_many]   
)) 
3

Como "vista permisos "will not make it into Django 1.11, desafortunadamente, aquí hay una solución que hace que su ModelAdmin de solo lectura por haciendo cambios en el modelo de guardado y agregando entradas de registro de historial de modelo a no-op.

def false(*args, **kwargs): 
    """A simple no-op function to make our changes below readable.""" 
    return False 

class MyModelReadOnlyAdmin(admin.ModelAdmin): 
    list_display = [ 
     # list your admin listview entries here (as usual) 
    ] 
    readonly_fields = [ 
     # list your read-only fields here (as usual) 
    ] 

    actions = None 
    has_add_permission = false 
    has_delete_permission = false 
    log_change = false 
    message_user = false 
    save_model = false 

(NOTA:. No se debe confundir el ayudante false no-op con la orden interna False Si no simpatizan con la función de ayuda fuera de la clase se mueve en la clase, o lo llaman no_op otra cosa, o invalidar los atributos afectados por habituales def s menos seco, pero si no le importa ...)

Esto hará lo siguiente:.

  1. eliminar las acciones cuadro desplegable (Con "eliminar") en la vista de lista
  2. entradas
  3. no permitir la adición de nuevo modelo
  4. disallow modelo borrar existente entradas
  5. evitar la creación de entradas de registro en la historia modelo
  6. no permita la visualización "se cambió correctamente" mensajes después de guardar
  7. ahorro de Evita changeform cambios en la base de datos

no lo hará:

  • quitar o sustituir los dos botones "Guardar y continuar con la edición" y "Guardar" (que sería bueno para mejorar la experiencia del usuario)

Tenga en cuenta que get_all_field_names (como se menciona en la respuesta aceptada) fue removed in Django 1.10. Probado con Django 1.10.5.

Cuestiones relacionadas