Django Admin: использование пользовательского виджета только для одного поля модели - PullRequest
57 голосов
/ 14 ноября 2010

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

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

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

Это недостаточно детально.Я хочу изменить его только для одного поля.

Ответы [ 4 ]

120 голосов
/ 10 марта 2011

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

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

class StopAdmin(admin.ModelAdmin):
  form = StopAdminForm

Готово! * * 1004

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

31 голосов
/ 16 ноября 2010

После копания в 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 }
    }

Выполняется работа.

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

16 голосов
/ 07 июня 2016

Переопределить 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/)

4 голосов
/ 18 сентября 2013

Модель Django 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 по этой теме

Надеюсь, это поможет

...