J'ai un champ DateTimeField dans mon modèle. Je voulais l'afficher en tant que widget de case à cocher dans le site d'administration Django. Pour ce faire, j'ai créé un widget de formulaire personnalisé. Cependant, je ne sais pas comment utiliser mon widget personnalisé pour seulement ce seul champ.
La documentation Django explique comment utiliser un widget personnalisé pour tous les champs d'un certain type:
class StopAdmin(admin.ModelAdmin):
formfield_overrides = {
models.DateTimeField: {'widget': ApproveStopWidget }
}
Ce n'est cependant pas assez granulaire. Je veux le changer pour seulement un champ.
Créez un ModelForm personnalisé pour votre ModelAdmin et ajoutez des "widgets" à sa classe Meta, comme ceci:
class StopAdminForm(forms.ModelForm):
class Meta:
model = Stop
widgets = {
'approve_ts': ApproveStopWidget(),
}
fields = '__all__'
class StopAdmin(admin.ModelAdmin):
form = StopAdminForm
Terminé!
La documentation pour cela est en quelque sorte placée de manière non intuitive dans les documents ModelForm, sans aucune mention à ce sujet dans les documents d'administration. Voir: Création de formulaires à partir de modèles
Après avoir creusé dans le code admin , champ modèle et champ formulaire , je crois que la seule façon de réaliser ce que je veux est de créer un personnalisé champ modèle:
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 }
}
Il fait le travail.
Pour l'instant, je vais laisser la question sans réponse car j'ai l'habitude de manquer l'évidence. Certains Django smartypants ont peut-être une meilleure solution.
Remplacez formfield_for_dbfield comme ceci:
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édit à http://www.kryogenix.org/days/2008/03/28/overriding-a-single-field-in-the-Django-admin-using-newforms-admin/ )
Le ModelAdmin.get_changelist_form de Django (self, request, ** kwargs) fera l'affaire pour le cas 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
Reportez-vous à documentation officielle de Django sur ce sujet
J'espère que cela vous aidera