Administrador de Django: ¿Cómo mostrar el campo marcado como “editable = Falso” en el modelo?

4 minutos de lectura

Avatar de usuario de GabiMe
gabime

Aunque un campo esté marcado como 'editable=False' en el modelo, me gustaría que la página de administración lo muestre. Actualmente, oculta el campo por completo. ¿Cómo se puede lograr esto?

avatar de usuario de tback
atrás

Usar Campos de solo lectura. Así (para django >= 1.2):

class MyModelAdmin(admin.ModelAdmin):
    readonly_fields=('first',)

  • +1. especialmente si tu no planee editar el campo en Admin.

    – Manoj Govindan

    19 de octubre de 2010 a las 16:05

  • Esto no funciona aquí (Django 2.0). El campo no se muestra en la interfaz de administración.

    – nerdoc

    5 de septiembre de 2018 a las 12:47

  • Acabo de crear una aplicación de muestra para reproducir su error (django 2.0.8, python 3.5). Esto todavía funciona bien. ¿Quizás algo más esté mal en tu aplicación @nerdoc?

    – tback

    5 de septiembre de 2018 a las 13:29


  • Ups. Tiro rápido típico. No probé, parece ser un problema con mi instalación. Gracias, y lo siento.

    – nerdoc

    6 sep 2018 a las 15:35

  • Para mí, el administrador se bloqueó cuando lo agregué a fieldspero cuando lo agregué a readonly_fields no apareció hasta que lo agregué a ambos y luego apareció en admin.

    – owenfi

    17 de septiembre de 2018 a las 6:04

Avatar de usuario de Manoj Govindan
Manoj Govindan

Actualizar

Esta solución es útil si desea mantener el campo editable en Admin pero no editable en el resto. Si desea mantener el campo no editable a lo largo de entonces la respuesta de @Till Backhaus es la mejor opción.

Respuesta Original

Una forma de hacer esto sería usar un personalizado ModelForm en administración Este formulario puede anular el campo obligatorio para hacerlo editable. De ese modo retienes editable=False en cualquier otro lugar excepto Admin. Por ejemplo (probado con Django 1.2.3)

# models.py
class FooModel(models.Model):
    first = models.CharField(max_length = 255, editable = False)
    second  = models.CharField(max_length = 255)

    def __unicode__(self):
        return "{0} {1}".format(self.first, self.second)

# admin.py
class CustomFooForm(forms.ModelForm):
    first = forms.CharField()

    class Meta:
        model = FooModel
        fields = ('second',)

class FooAdmin(admin.ModelAdmin):
    form = CustomFooForm

admin.site.register(FooModel, FooAdmin)

  • Esto no funciona, al menos en django 1.6. El formulario se muestra correctamente en el panel de administración, pero cuando guardo un formulario y vuelvo a él, el valor de los formularios vuelve a ser predeterminado.

    – Euforbio

    7 oct 2014 a las 12:42

avatar de usuario de gabriel
gabriel

Agregue los campos que desea mostrar en su página de administración.

Luego agregue los campos que desea que sean de solo lectura.

Sus campos de solo lectura deben estar en fields también.

class MyModelAdmin(admin.ModelAdmin):
    fields = ['title', 'author', 'published_date', 'updated_date', 'created_date']
    readonly_fields = ('updated_date', 'created_date')

  • Gracias, esto resolvió el problema para mí. simplemente pongo el readonly_fields encima y dejar fields ser los campos editables + readonly_fields (ambas son tuplas en mi código; no veo por qué uno las declararía como listas).

    – theberzi

    20 de octubre de 2020 a las 13:14

También puede configurar los campos de solo lectura como editable=False en el modelo (referencia de doc de django para editable aquí). Y luego en el administrador anulando el get_readonly_fields método.

# models.py
class MyModel(models.Model):
  first = models.CharField(max_length=255, editable=False)

# admin.py
class MyModelAdmin(admin.ModelAdmin):
  def get_readonly_fields(self, request, obj=None):
    return [f.name for f in obj._meta.fields if not f.editable]

Con la solución anterior, pude mostrar campos ocultos para varios objetos, pero obtuve una excepción al intentar agregar un nuevo objeto.

Así que lo mejoré de la siguiente manera:

class HiddenFieldsAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
    try:
        return [f.name for f in obj._meta.fields if not f.editable]
    except:
        # if a new object is to be created the try clause will fail due to missing _meta.fields
        return ""

Y en el archivo admin.py correspondiente, solo tenía que importar la nueva clase y agregarla cada vez que registraba una nueva clase de modelo.

from django.contrib import admin
from .models import Example, HiddenFieldsAdmin

admin.site.register(Example, HiddenFieldsAdmin)

Ahora puedo usarlo en todas las clases con campos no editables y hasta ahora no vi efectos secundarios no deseados.

Avatar de usuario de Bercove
Bercove

Puedes probar esto

@admin.register(AgentLinks)
class AgentLinksAdmin(admin.ModelAdmin):
    readonly_fields = ('link', )

Super Kai - Avatar de usuario de Kazuya Ito
Súper Kai – Kazuya Ito

Puedes mostrar editable=False campos con readonly_fields Como se muestra abajo:

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    readonly_fields = ('updated_date', 'created_date')

Y, si asigna editable=False campos a campostambién debe asignarlos a readonly_fields Como se muestra abajo:

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    fields = ('updated_date', 'created_date')
    readonly_fields = ('updated_date', 'created_date')

Porque, si sólo asignando editable=False campos a fields sin asignarlos a readonly_fields Como se muestra abajo:

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    fields = ('updated_date', 'created_date')
    # readonly_fields = ('updated_date', 'created_date')

Entonces, se produce el siguiente error:

django.core.exceptions.FieldError: ‘updated_date’ no se puede especificar para el formulario del modelo MyModel ya que es un campo no editable. Comprobar campos/conjuntos de campos/excluir atributos de la clase MyModelAdmin.

¿Ha sido útil esta solución?