Django admin – hace que todos los campos sean de solo lectura

Estoy tratando de hacer que todos los campos sean de solo lectura sin enumerarlos explícitamente.

Algo como:

class CustomAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): if request.user.is_superuser: return self.readonly_fields return self.fields 

El problema es que CustomAdmin.fields no está configurado en este punto.

¿Algunas ideas?

Cuidado, self.model._meta.fields no son necesariamente los mismos campos que CustomAdmin tiene!

“Todos los campos del administrador” se verían más así:

 from django.contrib import admin from django.contrib.admin.utils import flatten_fieldsets class CustomAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): if request.user.is_superuser: return self.readonly_fields 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] )) 

Ok, ahora hay esto:

 class CustomAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): # ... return [f.name for f in self.model._meta.fields] 

Sigo buscando un camino menos feo.

Podrías recorrer los meta campos del modelo:

 def get_readonly_fields(self, request, obj=None): if obj: self.readonly_fields = [field.name for field in obj.__class__._meta.fields] return self.readonly_fields 

Para Inlines (Tab o Stack)

 def get_readonly_fields(self, request, obj=None): fields = [] for field in self.model._meta.get_all_field_names(): if field != 'id': fields.append(field) return fields def has_add_permission(self, request): return False 

Esto me funcionó con Django 1.10.

 def get_readonly_fields(self, request, obj=None): if request.user.is_superuser: return self.readonly_fields return list(set( [field.name for field in self.opts.local_fields] + [field.name for field in self.opts.local_many_to_many] )) 

puedes hacer esto:

 class CustomAdmin(admin.ModelAdmin): def has_change_permission(self, request, obj=None): return False 

Mi requerimiento era similar. Solo necesitaba que un campo se mostrara como de solo lectura. Y esto funcionó bien:

 class ChoiceInline(admin.TabularInline): model = Choice extra = 1 fields = ['choice_text', 'votes'] readonly_fields = ['votes'] class QuestionAdmin(admin.ModelAdmin): #fields = ['pub_date', 'question_text'] fieldsets = [ (None, {'fields': ['question_text']}), ('Date Information', {'fields': ['pub_date']}), ] search_fields = ['question_text'] inlines = [ChoiceInline] 

Consulte : C: \ Python27 \ Lib \ site-packages \ django \ contrib \ admin \ options.py

Con get_fieldsets obtienes todos los campos del formulario

 def get_readonly_fields(self, request, obj=None): readonly = [] for fs in self.get_fieldsets(request, obj): if len(fs) > 1: readonly += fs[1].get('fields', []) return readonly