Как изменить виджет по умолчанию для всех встроенных полей формы определенного типа в Django?
Это продолжение Как изменить виджет по умолчанию для всех полей даты Django в форме модели?.
Предположим, у вас есть очень большое количество моделей (например, A-ZZZ), которые растут с вводом других разработчиков, которые находятся вне вашего контроля, и вы хотите изменить способ ввода всех полей даты (например, с помощью jQueryUI). Как лучше всего обеспечить заполнение всех полей даты с помощью этого нового виджета?Одно предложение из приведенного вопроса было:
def make_custom_datefield(f):
if isinstance(f, models.DateField):
# return form field with your custom widget here...
else:
return f.formfield()
class SomeForm(forms.ModelForm):
formfield_callback = make_custom_datefield
class Meta:
# normal modelform stuff here...
Однако возможно ли это сделать там, где у вас нет явных шаблонов ModelForm, но шаблоны url приходят непосредственно из моделей? то есть Ваш url config выглядит следующим образом:
url(r'^A/?$', 'list_detail.object_list', SomeModelA)
Где SomeModelA-это модель (не форма), которая была превращена в ModelForm Джанго в фоновом режиме.
В настоящее время в моей системе нет форм для каждой модели. Единственным моментом явного создания форм было бы добавление formfield_callback, предложенного в предыдущем решении, но это идет против сухих принципов, и был бы подвержен ошибкам и трудоемким.Я рассматривал (как было предложено в последнем потоке) создание моего собственного поля, которое имеет специальный виджет и использует его вместо встроенного. Это не так трудоемко, но это может быть подвержено ошибкам (ничего хорошего grep не мог исправить, хотя).
Предложения и мысли приветствуются.
1 ответ:
Похоже, что вы хотите сделать это в рамках всего проекта (т. е.: вы не пытаетесь сделать это в некоторых случаях, но во всех случаях в вашем запущенном приложении).
Одна из возможностей заключается в замене атрибута widget самого класса DateField. Вам нужно будет сделать это в каком-нибудь центральном месте... что-то, что гарантированно будет загружено каждым запущенным экземпляром приложения django. Промежуточное программное обеспечение может помочь в этом. В противном случае просто поместите его в файл
__init__
вашего приложения.Что вы хотите do-это повторно назначить свойство виджета для форм.Дата самого класса. При создании нового поля даты Django проверяет, указывает ли код какой-либо конкретный виджет в определении свойства поля. Если нет, то используется поле по умолчанию для даты. Я предполагаю, что если пользователь в вашем сценарии действительно определил конкретный виджет, вы захотите выполнить это, несмотря на изменение вашего глобального API.
Попробуйте это в качестве примера принудительного применения значения по умолчанию к какому-либо другому виджету... в этом случае HiddenInput:
from django import forms forms.DateField.widget = forms.HiddenInput class Foo(forms.Form): a = forms.DateField() f = Foo() print f.fields['a'].widget # results in <django.forms.widgets.HiddenInput object at 0x16bd910>