在modelformset_factory中使用带有自定义字段小部件的表单?

时间:2012-01-20 11:08:36

标签: django django-forms

我正在尝试在modelformset_factory using jquery.formset.js中创建自定义表单。 这是一个代码:

自定义表单类:

class CustomizedForm(forms.ModelForm):
    date = forms.DateField(widget=JQueryUIDatepickerWidget, required=True )
    time_begin = forms.TimeField(widget=JQueryUITimePickerWidget, required=True, initial=time(0, 0))
    time_end = forms.TimeField(widget=JQueryUITimePickerWidget, required=True, initial=time(23,59))

    def __init__(self, *args, **kwargs):
        super(CustomizedForm, self).__init__(*args, **kwargs)

自定义formset类:

class FormSetWithInitialValues(BaseModelFormSet):
    def __init__(self, initials, **kwargs):
        super(FormSetWithInitialValues, self).__init__(**kwargs)
        self.initials = initials

    def save_new(self, form, commit=True):
        for k, val in self.initials.items():
            form.cleaned_data[k] = val
        return form.save(commit=commit)

Formset工厂:

Formset = modelformset_factory(
                    MyModel,
                    formset=FormSetWithInitialValues,
                    form=CustomizedForm,
                    can_delete=True,
                    extra=1,
                )

接下来是问题所在。当我初始化页面时,所有现有的formset都使用小部件初始化。但是当我尝试向formset添加新表单时,表单是create,但是小部件不与表单的字段绑定。问题是,如何将小部件与新表单的字段绑定?

2 个答案:

答案 0 :(得分:0)

图拉尔,

我不明白你的问题。但是,我发布了我的代码。我希望这对你有所帮助。这是第一种方法,我们可以改进答案。

formset_f = modelformset_factory(  ItemQualitativa, extra=20 )

if request.method == 'POST':
    formset = formset_f(request.POST)
    if formset.is_valid():
        formset.save()
else:
    formset = formset_f()

for form in formset:
    form.fields['text'].widget.attrs['size'] = 70 #<-try change widget here.

我不明白你的问题是这句话:&#34;但是当我尝试在formset中添加新表单时,表单就是创建&#34;。什么时候尝试添加新表格?

问候。

答案 1 :(得分:0)

接下来解决问题。当我们向formset添加一个新表单时,jquery只复制与表单字段对应的隐藏的html行,清除它并提供新的ID。但它不会复制有关小部件的信息。所以我们应该使用js-callback函数,它在new form到formset add之后调用:

<script src="{{ STATIC_URL }}js/jquery.formset/jquery.formset.js" type="text/javascript"></script>
<script type="text/javascript">

$(function() {
    {% if formset %}
        var datepickerConfig = {};
        datepickerConfig.__proto__ = DatePickerConfig;
        var timepickerConfig = {};
        timepickerConfig.__proto__ = TimePickerConfig;

        $('.calendar_formset_tr').formset({
            prefix : '{{ formset.prefix|escapejs }}',
            deleteText: '&nbsp;<img src="{{ STATIC_URL }}images/icons/delete.png" />',
            addText: '&nbsp;<img src="{{ STATIC_URL }}images/icons/add.png" />',
            addCssClass: 'add_link',
            deleteCssClass: 'remove_link',
            added: function (row) {
                var datePicker = $(row).find('input[name$="date"]');
                if (datePicker.length > 0) {
                    //привязка виджета
                    datePicker.datepicker('destroy').datepicker(datepickerConfig);
                }

                var timeBeginPicker = $(row).find('input[name$="time_begin"]');
                var timeEndPicker = $(row).find('input[name$="time_end"]');
                if (timeBeginPicker.length > 0 && timeEndPicker.length > 0) {
                    //привзяка виджета и проставление значения по-умолчанию
                    timeBeginPicker.val("00.00");
                    timeBeginPicker.timepicker('destroy').timepicker(timepickerConfig);
                    timeEndPicker.val("23.59");
                    timeEndPicker.timepicker('destroy').timepicker(timepickerConfig);
                }
            }
        });
    {% endif %}
});
</script>