Django Admin: использование настраиваемого виджета только для одного поля модели
В моей модели есть поле DateTimeField. Я хотел показать его как виджет-флажок на сайте администратора Django. Для этого я создал виджет пользовательской формы. Однако я не знаю, как использовать свой собственный виджет для только этого поля.
Документация Django объясняет, как использовать пользовательский виджет для полей all определенного типа:
class StopAdmin(admin.ModelAdmin):
formfield_overrides = {
models.DateTimeField: {'widget': ApproveStopWidget }
}
Это не достаточно гранулировано. Я хочу изменить его только для поля one.
Ответы
Ответ 1
Создайте собственный ModelForm для вашего ModelAdmin и добавьте "виджеты" в свой класс Meta, например:
class StopAdminForm(forms.ModelForm):
class Meta:
model = Stop
widgets = {
'approve_ts': ApproveStopWidget(),
}
fields = '__all__'
class StopAdmin(admin.ModelAdmin):
form = StopAdminForm
Готово!
Документация для этого типа не интуитивно размещена в документах ModelForm, без каких-либо упоминаний в документе admin. См.: Создание форм из моделей
Ответ 2
После перехода в 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 smartypants есть лучшее решение.
Ответ 3
Переопределите 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
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 Официальная документация по этому вопросу
Я надеюсь, что это поможет