I'm trying to use inlineformset_factory to generate a series of number boxes within a table to update the additional field in a through table from a self referential many-to-many relationship.
views.py
def edit_assembly(request, slug):
root = Part.objects.get(slug=slug)
forms = inlineformset_factory(Part, Relationship, fields=('qty',), fk_name="child", can_delete=False)
if request.method == 'POST':
formset = forms(request.POST)
if formset.is_valid():
formset.save()
else:
formset = forms(instance=root)
return render(request, "app/edit_assembly.html", {
"formset": formset
})
models.py
class Part(models.Model):
part_number = models.IntegerField()
slug = models.SlugField(unique=True)
name = models.CharField(max_length=40)
children = models.ManyToManyField(
'self', symmetrical=False, through='Relationship', through_fields=('parent', 'child'), blank=True)
class Relationship(models.Model):
qty = models.IntegerField(default=1)
parent = models.ForeignKey(
Part, on_delete=models.CASCADE, related_name='parent', null=True)
child = models.ForeignKey(
Part, on_delete=models.CASCADE, related_name='child', null=True)
template:
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form }} <br>
{% endfor %}
<input type="submit" value="Submit">
</form>
Whatever I try I cannot seem to return a valid form. When I look at the page source with my browser the ID's that are assigned to the hidden fields in each form are not what I would expect. currently am experiencing the error: "(Hidden field child) The inline value did not match the parent instance."
I suspect the hidden field child should contain the foreign key for the part, it doesn't seem to however.
-- edit --
I realised that I should be using fk_name="parent", so this line now reads:
forms = inlineformset_factory(Part, Relationship, fields=('qty',), fk_name="parent", can_delete=False, extra=0)
With this, when I look at the source in my browser I'm now seeing:
<input type="number" name="parent-0-qty" value="2" id="id_parent-0-qty">
<input type="hidden" name="parent-0-id" value="10013" id="id_parent-0-id">
<input type="hidden" name="parent-0-parent" value="10058" id="id_parent-0-parent">
This seems correct, 10058 is the primary key for the Part, 10013 is a primary key for the Relationship.
Still getting an error: (Hidden field parent) The inline value did not match the parent instance.
Still not sure what that wasn't working but I managed to quite simply do what I wanted with modelformset_factory instead:
def edit_assembly(request, slug):
root = Part.objects.get(slug=slug)
AssemblyFormset = modelformset_factory(Relationship, fields=('qty',), extra=0)
if request.method == 'POST':
formset = AssemblyFormset(request.POST, queryset=root.parent.all())
if formset.is_valid():
formset.save()
else:
formset = AssemblyFormset(queryset=root.parent.all())
return render(request, "PaNDa/edit_assembly.html", {
"formset": formset
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.