Django Admin: использование пользовательского виджета только для одного поля модели


У меня есть DateTimeField поле в моей модели. Я хотел отобразить его как виджет флажка на сайте администратора Django. Для этого я создал пользовательский виджет формы. Однако, я не знаю, как использовать мой пользовательский виджет для только это одно поле.

на документация Django объясняет, как использовать пользовательский виджет для все поля определенного типа:

class StopAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.DateTimeField: {'widget': ApproveStopWidget }
    }

Это не достаточно гранулированный, хотя. Я хочу измените его только на один

4 53

4 ответа:

создайте пользовательскую модель для вашего ModelAdmin и добавьте "виджеты" в свой мета-класс, например:

class StopAdminForm(forms.ModelForm):
  class Meta:
    model = Stop
    widgets = {
      'approve_ts': ApproveStopWidget(),
    }
    fields = '__all__'

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

готово!

документация для этого является своего рода неинтуитивно помещенной в документы ModelForm, без какого-либо упоминания об этом в документах администратора. Смотрите: создание форм из моделей

после копания в admin,модели месторождения и поле код, я считаю, что единственный способ выполнить то, что я хочу, это создать пользовательское поле модели:

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 }
    }

он выполняет свою работу.

на данный момент я оставлю вопрос без ответа, потому что у меня есть привычка упускать очевидное. Возможно, некоторые умники Джанго лучше решение.

переопределить formfield_for_dbfield следующим образом:

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)

(кредит http://www.kryogenix.org/days/2008/03/28/overriding-a-single-field-in-the-django-admin-using-newforms-admin/ )

ModelAdmin Джанго.get_changelist_form(self, request, * * kwargs) сделает трюк для случая 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

смотрите официальная документация Django по этой теме

Я надеюсь, что это поможет