如何使用具有动态数量的相关对象的ModelForm?

时间:2012-11-15 19:35:33

标签: python django django-models django-forms

以下是我的模型设置方式:

class ModelA(models.Model):
    user = models.ForeignKey(User)
    modelB = models.ForeignKey('ModelB', related_name='modelB')
    # more fields here

class ModelB(models.Model):
    user = models.ForeignKey(User)
    # more fields here

这两个类中的用户字段只是为了以后可以由同一个用户查询这两个字段。

我有ModelB的ModelForm,我希望用户能够使用动态数量的ModelA实例填写ModelB ModelForm。我希望ModelB的表单从1个ModelA实例开始填写,然后用户应该能够将更多的ModelA添加到ModelB的表单中。

我坚持这个作为个人项目,并且真的想继续前进。谢谢你的帮助!

编辑1:我知道我很可能需要通过重载ModelForms def __init__来完成一些工作,但这就是我所知道的。此外,我正在使用ClassBasedGeneric Views(CreateView以便稍后进行添加工作和EditView),但如果需要,我愿意放弃它。

1 个答案:

答案 0 :(得分:1)

您需要django inline formset

在视图中:

f_set = inlineformset_factory(ModelB, ModelA, extra=1)

在模板中,假设您要在div中呈现form_set,其id为one_to_many

<form>
   <div id="one_to_many">
       {{f_set.as_table}}
   </div>
</form>

#This will render some thing like this
<form>
    <div id="one_to_many">
        <table>
            <tr>
               <th>
                   <label for="id_form-0-field_name">Field Name:</label>
               </th>
               <td>
                  <input id="id_form-0-field_name" type="text" name="form-0-field_name" value="" maxlength="100" />
                  <input type="hidden" name="form-0-id" value="1" id="id_form-0-id" />  
                </td>
            </tr>
        </table>
        <input type="button" value="Add More Field" id="add_more">
    </div>
</form>

现在jquery部分动态添加字段:

$(document).ready(function(){
        $('#add_more').click(function(){
            var tbl = $('#one_to_many').children('table');
            var last_id = parseInt(tbl.find('input[type=hidden]').last().val());
            var next_id = last_id + 1;
            htm = '<tr><th><label for="id_form-'+last_id+'-field_name">Field Name:</label></th><td><input id="id_form-'+last_id+'-field_name" type="text" name="form-'+last_id+'-field_name" value="" maxlength="100" /><input type="hidden" name="form-'+last_id+'-id" value="'+next_id+'" id="id_form-'+last_id+'-id" /></td></tr>'
            tbl.find('tr').last().after(htm);

        });    
    });

您可以在jsfiddle上对此进行测试。请注意,只有在呈现表单as_table

时,此功能才有效