[Django]-Django โ€“ Establishing Many To Many Relationship Between 2 Models Without Through Table Using Formsets

0๐Ÿ‘

Try something like this:

from django.forms.models import modelformset_factory
def my_view_function(request) :

    # not sure where the product whose formset we are working on comes from
    product = <whatever>

    AttributeFormSet = modelformset_factory(Attribute)

    if request.method == "POST" :
        # POST bound formset
        formset = AttributeFormSet(request.POST, queryset=Attribute.objects.filter(product=product))
        # If the entire formset is valid
        if formset.is_valid() :
            for form in formset:
                # Save each form in the set
                b = form.save()
        else : 
            #There was an error (add a message using the messages framework?)
            pass
    else :
        # initial formset w/o post
        formset = AttributeFormSet(queryset=Attribute.objects.filter(product=product))

    ...

Its kind of hard to give you more specific answer, I think we would need the entire view function or view class if you are using class based views.

In your template, something as simple as this (from the docs) should do it.

<form method="post" action="">
    {{ formset.management_form }}
    <table>
        {% for form in formset %}
        {{ form }}
        {% endfor %}
    </table>
</form>

If you need the ability to add forms to the formset at runtime w/ javascript look at this: http://code.google.com/p/django-dynamic-formset/. Ive never used it, but at the very least it looks like a step in the correct direction.

EDIT

First exclude product from the formset

AttributeFormSet = modelformset_factory(Attribute, exclude=('product',))

then change the form processing block to not commit on save, and manually attach the product.

        if formset.is_valid() :
            for form in formset:
                # get this form's instance
                b = form.save(commit=False)
                # attach product
                b.product = product
                # save the instance
                b.save()

0๐Ÿ‘

By using f = form.instance you access the original instance. If the attribute_form is valid you call the save method on the form, instead of the f. All the changes you did on f will be lost.

Have a look at saving-objects-in-the-formset how to update instances of a formset before saving them.

๐Ÿ‘คWillian

Leave a comment