python - tutorial - Django Admin: usando un widget personalizado para un solo campo de modelo
tutorial django (4)
Cree un ModelForm personalizado para su ModelAdmin y agregue ''widgets'' a su clase Meta, así:
class StopAdminForm(forms.ModelForm):
class Meta:
model = Stop
widgets = {
''approve_ts'': ApproveStopWidget(),
}
fields = ''__all__''
class StopAdmin(admin.ModelAdmin):
form = StopAdminForm
¡Hecho!
La documentación para esto se coloca de forma no intuitiva en los documentos de ModelForm, sin que se mencione en los documentos de administración. Ver: Creación de formularios a partir de modelos.
Tengo un campo DateTimeField en mi modelo. Quería mostrarlo como un widget de casilla de verificación en el sitio de administración de Django. Para hacer esto, creé un widget de formulario personalizado. Sin embargo, no sé cómo usar mi widget personalizado solo para este campo.
La documentación de Django explica cómo usar un widget personalizado para todos los campos de un determinado tipo:
class StopAdmin(admin.ModelAdmin):
formfield_overrides = {
models.DateTimeField: {''widget'': ApproveStopWidget }
}
Sin embargo, esto no es lo suficientemente granular. Quiero cambiarlo por un solo campo.
Después de profundizar en el código de campo de formulario, campo de admin y admin , creo que la única forma de llevar a cabo lo que quiero es crear un campo de modelo personalizado:
models.py
from django.db import models
from widgets import ApproveStopWidget
class ApproveStopModelField(models.DateTimeField):
pass
class Stop(models.model):
# Other fields
approve_ts = ApproveStopModelField(''Approve place'', null=True, blank=True)
admin.py
from widgets import ApproveStopWidget
from models import ApproveStopModelField
class StopAdmin(admin.ModelAdmin):
formfield_overrides = {
ApproveStopModelField: {''widget'': ApproveStopWidget }
}
Se hace el trabajo.
Por el momento, dejaré la pregunta sin responder porque tengo la costumbre de pasar por alto lo obvio. Tal vez algunos smartypants de Django tengan una mejor solución.
El ModelAdmin.get_changelist_form de Django (self, request, ** kwargs) hará el truco para el caso de list_editable
class StopAdminForm(forms.ModelForm):
class Meta:
model = Stop
widgets = {
''approve_ts'': ApproveStopWidget(),
}
class StopAdmin(admin.ModelAdmin):
form = StopAdminForm
#just return the ModelForm class StopAdminForm
def get_changelist_form(self, request, **kwargs):
return StopAdminForm
Consulte la documentación oficial de Django sobre este tema.
Espero que esto sea de ayuda
Sobrescribir formfield_for_dbfield de esta manera:
class VehicleAdmin(admin.ModelAdmin):
search_fields = ["name", "colour"]
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == ''colour'':
kwargs[''widget''] = ColourChooserWidget
return super(VehicleAdmin,self).formfield_for_dbfield(db_field,**kwargs)
(crédito a http://www.kryogenix.org/days/2008/03/28/overriding-a-single-field-in-the-django-admin-using-newforms-admin/ )