1

I have a many-to-many relationship between two classes (Lesson and Student), with an intermediary class (Evaluation).

I am trying to set up a form which will allow me to add a lesson with students and the related evaluation data. I can get all of the fields I want to display correctly, however I also need to set an initial value behind the scenes (the current user), as it does not make sense to have it in the form.

I have tried following the docs but I think I have a syntax error in the way I am passing the data to the formset.

The error I receive is as follows:

__init__() got an unexpected keyword argument 'initial'

My actual view (with my attempt at adding the initial data removed) looks like this:

def addlesson(request):
LessonFormset = inlineformset_factory(Lesson, Evaluation, exclude=('user',), max_num=5)
if request.method == 'POST':
    lesson = Lesson(user=request.user)
    form = LessonForm(request.POST, instance=lesson, user = request.user)
    formset = LessonFormset(request.POST, instance = lesson)
    if form.is_valid() and formset.is_valid():
        form.save()
        formset.save()
        return HttpResponseRedirect("/")
else:
    form = LessonForm(user = request.user)
    formset = LessonFormset()
return render_to_response("addlesson.html", {
    'form': form,
    'formset' : formset,
}, context_instance=RequestContext(request))

Could anyone show me to correct syntax to use to set the current user in the formset? This is what I had before but it was giving me the error at the start of my post:

initial={'user': request.user},

Any advice appreciated

Thanks

1

2 Answers 2

4

It's not clear to me why you are using a formset when it looks like you only want to add one row. A regular form would have been how I would do it if there was only one row. But, here's how I set the default value in a formset.

I exclude the field, just like you already have in your code. Then:

if form.is_valid() and formset.is_valid():
    form.save()
    models = formset.save(commit=False)
    for i in models:
        i.user = request.user
        i.save()
    return HttpResponseRedirect("/")
Sign up to request clarification or add additional context in comments.

2 Comments

Sorry, if it was misleading, I had max_num=1 just to simplify the form was testing it with. It could use a lot more.
Sorry, so did my response answer your question about initial/default values on formsets? I ask because you have neither accepted my answer nor clarified what you are looking for.
0

I tried Umang's answer and it didn't work good for when you want to change a value with a specific index. When you save the formset it will change the values that was changed.

But if you change models = formset.save(commit=False) to models = formset

and then you also need to change i.user = request.user to i.instance.user = request.user

 if form.is_valid() and formset.is_valid():
        form.save()

        # changed to formset instead of formset.save(commit=False)
        models = formset

        for model in models:
           
            # changed to i.instance.user instead of i.user, except renamed i to model.
            model.instance.user = request.user

            model.save()

            # save the formset
            formset.save()

        return HttpResponseRedirect("/")

Now when you want to change an index it will include all the forms, not only the ones that was changed when you save.

Example:

views.py

if form.is_valid() and formset.is_valid():
        form.save()

        models = formset
        index = 0
           
        # This will only change the first form in the formset.
        models[index].instance.user = request.user

        models.save()

        formset.save()
        return HttpResponseRedirect("/")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.