Reputation: 2718
Here is how my models are setup:
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
The user field in both classes are just so that both of these can be queried by the same user later on.
I have a ModelForm of ModelB and I would like to have the users be able to fill out a ModelB ModelForm with a dynamic number of ModelA instances. I would like ModelB's form to start out with 1 instance of ModelA to fill out and then the user should be able to add more ModelA's to ModelB's form.
I'm stuck on this as a personal project and would really like to move forward. Thanks for any help!
Edit 1: I know that I will most likely need to do some work by overloading ModelForms def __init__
, but that is about as far as I have gotten. Also I am using ClassBasedGeneric Views (CreateView to get the add working and an EditView later on), but I am willing to move away from that if needed.
Upvotes: 0
Views: 78
Reputation: 39659
You require django inline formset
In view:
f_set = inlineformset_factory(ModelB, ModelA, extra=1)
In template lets suppose you are rendering form_set in a div
whose id is 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>
Now the jquery
part to add field dynamically:
$(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);
});
});
You can test this on jsfiddle. Note this will only work if you render your form as_table
Upvotes: 1