Django admin-faire tous les champs en lecture seule

j'essaie de rendre tous les champs lisibles sans les lister explicitement.

quelque chose comme:

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

        return self.fields

le problème est CustomAdmin.fields n'est pas réglé à ce point.

des idées?

22
demandé sur yprez 2012-12-11 13:47:06

7 réponses

attention, self.modèle._meta.les champs ne sont pas nécessairement les mêmes que ceux de CustomAdmin!

"tous les champs de L'Admin" ressembleraient plus à ceci:

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]
            ))
31
répondu Danny W. Adair 2017-01-25 12:27:49

Ok, maintenant il y a ceci:

class CustomAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        # ...

        return [f.name for f in self.model._meta.fields]

toujours à la recherche d'un chemin moins laid.

17
répondu yprez 2012-12-11 10:37:22

vous pouvez itérer à travers les méta-champs du modèle:

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
8
répondu Hedde van der Heide 2014-05-05 18:32:38

Pour les Inlines (Onglet ou la Pile)

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
5
répondu Ohad the Lad 2018-02-27 15:23:38

cela a fonctionné pour moi avec 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]
    ))
3
répondu user2111922 2017-03-18 17:21:11

Mon exigence était similaire . J'avais besoin du champ d'un seul champ pour être affiché en lecture seule . Et cela a bien fonctionné:

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]

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

0
répondu Arindam Roychowdhury 2018-02-27 11:40:46

avec get_fieldsets vous obtenez tous les champs du formulaire

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
-1
répondu pgranger 2013-10-11 12:37:54