简体   繁体   中英

Using inlineformset_factory getting incorrect id's from foreign key

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM