Python >> Tutoriel Python >  >> Python

Django Admin :Utilisation d'un widget personnalisé pour un seul champ de modèle

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éer des formulaires à partir de modèles


Après avoir creusé dans l'administrateur, le champ de modèle et le code de champ de formulaire, je pense que la seule façon de réaliser ce que je veux est de créer un champ de modèle personnalisé :

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 laisse la question sans réponse car j'ai l'habitude de passer à côté de l'évidence. Peut-être que certains smartypants Django ont 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/)