Используя knockout.js с формами django?

Я хочу добавить некоторую структуру в свой код на стороне клиента и читал о knockout.js. Я читал документацию и задавал простой вопрос: поскольку нокаут требует, чтобы пользователь добавлял атрибуты data-bind к элементам html, что лучше всего подходит для работы с формами django, так как в настоящее время я используя {{ form.as_p }}

Мне любопытно, как и где я должен вставлять входы в view model (если он находится в полях формы в Django или forfeiting {{ form.as_p }} и вместо этого выводит текст в html.

Ответы

Ответ 1

Вы можете добавить пользовательские атрибуты в свои поля в определении формы Meta с помощью виджетов.

class SomeForm(forms.ModelForm):
    class Meta:
        model = SomeModel
        widgets = {'field_name1': forms.Textarea(attrs={'data-bind':'value: field1'}),
                   'field_name2': forms.TextInput(attrs={'data-bind':'value: field2'})}

Например, будет показано первое поле:

<textarea id="id_field_name1" name="field_name1" data-bind="value: field1"></textarea>

Update: в качестве бонуса здесь есть простой способ изменить атрибут для каждого поля в форме, например, если все они нуждаются в определенном классе (полезен для других js-аддонов или стилей CSS)

    def __init__(self, *args, **kwargs):
        super(SomeForm, self).__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs['class'] = 'some_form_field'
            # this could be used in your case if the Django field name is the
            # same as the KO.js field name
            field.widget.attrs['data-bind'] = 'value: %s' % name

Ответ 2

Другим способом является использование django-crispy-forms и определение атрибутов data-bind в layout:

def __init__(self, *args, **kwargs):
    super(SomeForm, self).__init__(*args, **kwargs)
    self.helper = FormHelper()
    self.helper.layout = Layout(
        Div('field_1',
            Field('field_2', data_bind='value: field_2')),
        HTML("{% if success %} <p data-bind="css: { success: success_flag }">Operation was successful</p> {% endif %}"),
    )

Затем в шаблоне вы делаете следующее:

{% crispy form form.helper %}

и вуаля.

Крипси-формы еще более мощные, чем это, и позволяет вам определять свои собственные шаблоны макета и т.д.