Cuando dispones de un panel Administrativo en Django, automáticamente se crear desplegables (Select
) con las claves foráneas. El problema llega cuando necesitas editar sus valores de cara al visitante, solo texto de cada elemento. No existe una herramienta en un ModelAdmin
que te permita editar la forma en la cual se muestran los valores de un campo que está relacionado con un Modelo.
La manera de lograrlo, sintetizando, es crear un ModelForm
a medida con un campo de tipo ModelChoiceField
y continuación sobrescribir el atributo form
del ModelAdmin
.
Suena complicado pero no es para tanto. Además el esfuerzo vale la pena ya que nos permite definir más elementos como una queryset
a personalizada.
En el tutorial voy a dar solución al siguiente problema: Dispongo de un modelo llamado Product
(Producto) que lista Category
(Categorías), y necesito que todas las categorías se muestren en mayúsculas.
Queremos pasar de esto:
a esto:
¡Vamos a por ello!
1. Creamos formulario a medida
Vamos a definir un formulario que contenga un campo que sea un desplegable generado a partir de una queryset
.
Empezamos declarando un campo desplegable con ModelChoiceField
.
Añadimos en forms.py
:
class CustomCategoryChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.name.upper()
La función label_from_instance
la debes sobreescribir para cambiar el texto que será mostrando por cada elemento. Dispones de cada iteración de obj
. En mi caso utilizo el campo name
de mi modelo Category
.
A continuación, declaramos el formulario usando un ModelForm
e incluimos el campo anterior.
from .models import Category
class ProductCustomForm(forms.ModelForm):
category = CustomCategoryChoiceField(
label="Categoría",
queryset=Category.objects.all().order_by("name"),
)
class Meta:
model = Product
fields = "__all__"
En el Meta
hemos incluido el modelo que usará para construir el formulario, con fields
le hemos configurado los campos que queremos (todos) y con category
hemos sobrescrito el campo que nos interesa con CustomCategoryChoiceField
.
2. Incluir formulario en el Administrador
Nos dirigimos a admin.py
e insertamos el formulario en el ModelAdmin
que tenemos la intención de modificar.
from .forms import ProductCustomForm
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
form = ProductCustomForm # Nuevo
# Tus cosas
ordering = ["-created_at"]
search_filter = ["name", "category", "price"]
...
Y ya estaría.
Debes ser consciente que estas modificando todo el formulario del ModelAdmin
, ahora el control de los campos que estas mostrando se encuentra en ProductCustomForm
. Cualquier intento de mezclar diferentes formularios serán en vano.
Espero que este artículo haga la vida más fácil a vuestro clientes.
Quiero agradecer a Newbedev por servirme de inspiración con el artículo How to override default display values for a select field for foreign keys in the Django Admin.
{{ comments.length }} comentarios