django - как получить доступ к полю формы из пользовательского виджета
приведенный ниже класс наследуется от Textarea виджет и функции javascript-код, который отображает, сколько символов больше пользователь может ввести в textarea.
class TextAreaWithCharCounter(forms.Textarea):
class Media:
js = ('js/jquery.charcounter.js',)
def render(self, name, value, attrs = None):
id = attrs['id']
max_length = self.attrs.get('max_length', 200)
output = super(TextAreaWithCharCounter, self).render(name, value, attrs)
output += mark_safe(u'''
<script type="text/javascript">
$("#%s").charCounter(%d, {classname:"charcounter"});
</script>'''%(id, max_length))
return output
соответствующая часть кода формы выглядит следующим образом:
class MyForm(forms.Form):
foo = forms.CharField(max_length = 200, widget = TextAreaWithCharCounter(attrs={'max_length':200}))
...
вы можете видеть, что я прохожу max_length
аргумент дважды, один для поля и один для виджета. Лучшим способом может быть доступ к полю формы изнутри виджета и получение его атрибута max_length, так что аргумент max_length не требует виджет. Как я могу это сделать?
2 ответов
технически виджет не должен иметь прямого отношения к полю, поэтому вы этого не делаете.
смотреть на!--12-->источник CharField
, вы можете видеть, что у него есть widget_attrs
метод, который автоматически добавляет до TextInput
/ PasswordInput
поля.
Я предлагаю вам использовать настраиваемое поле, которое переопределяет этот метод и добавляет атрибут для вашего настраиваемого виджета.
кроме того, я не уверен, что оставляя его в attrs
is в любом случае, хорошая идея -<TextArea>
будет отображаться с недопустимым
хотя это не требуется для решения вашей проблемы, доступ к форме или полю формы может быть действительно полезен иногда. См. полный ответ на еще вопрос, но, короче говоря, вы можете привязать форму или поле к виджету вручную в форме __init__
:
class MyForm(forms.ModelForm):
foo = forms.ModelChoiceField(Foo.objects, widget=CustomWidget())
class Meta:
model = Bar
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['foo'].widget.form_instance = self