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

Dan
  • 6,265
  • 8
  • 40
  • 56
  • Take a look at this post for some ideas: http://stackoverflow.com/questions/622982/django-passing-custom-form-parameters-to-formset – Nick Craig-Wood Jul 17 '11 at 20:11

2 Answers2

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("/")
Umang
  • 5,196
  • 2
  • 25
  • 24
  • 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. – Dan Jul 17 '11 at 20:04
  • 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. – Umang Jul 18 '11 at 00:59
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("/")
AnonymousUser
  • 690
  • 7
  • 26