1

I initially wrote code to build a form dynamically, based on data from the DB, similar to what I described in my previous SO post.

As SO user Daniel Roseman points out, he would use a formset for this, and now I've come to the realization that he must be completely right. :)

My approach works, basically, but I can't seem to get validation across the entire form to be working properly (I believe it's possible, but it's getting quite complex, and there has to be a smarter way of doing it => Formsets!).

So now my question is: How can I build a formset dynamically? Not in an AJAX way, I want each form's label to be populated with an FK value (team) from the DB.

As I have a need for passing parameters to the form, I've used this technique from a previous SO post.

With the former approach, my view code is (form code in previous link):

def render_form(request):
  teams = Team.objects.filter(game=game)
  form_collection = [] 
  for team in teams:
            f = SuggestionForm(request.POST or None, team=team, user=request.user)
            form_collection.append(f)

Now I want to do something like:

def render_form(request):
  teams = Team.objects.filter(game=game)
  from django.utils.functional import curry
  from django.forms.formsets import formset_factory

  formset = formset_factory(SuggestionForm)
  for team in teams:
      formset.form.append(staticmethod(curry(SuggestionForm, request.POST or None, team=team, user=request.user)))

But the append bit doesn't work. What's the proper way of doing this?

Thanks!

1 Answer 1

4

Thanks for the recognition of my unvarying rightness...

Probably what you need here is a model formset, which will automatically build itself from a queryset you pass in:

from django.forms.models import modelformset_factory

def render_form(request):
    teams = Team.objects.filter(game=game)
    formset = modelformset_factory(form=SuggestionForm, queryset=teams)

As for the dynamic parameter, which I'm guessing is user, I've previously used the closure solution, but the curry method should still work:

    formset.form = staticmethod(curry(SuggestionForm, user=request.user))

Edit after comment Thanks for the clarification. I think I understand what you're trying to do. I wonder if an inline formset might work better? If you started off with a Game object pre-populated with eight related Team objects, an inline formset would give you eight pre-existing forms.

my_game = Game.objects.create(params=whatever)
for i in range(1, 9):
    team = Team.objects.create(game=my_game, name="team_%s" % i

formset = inlinemodelformset_factory(Game, Team, form=SuggestionForm)
fs = formset(instance=my_game)

Does that work?

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, and you're welcome :). Now I get a single Form with drop down for teams. I want to have each team as a label in a Form and use radio buttons for the choices. Which means that if I've 8 teams, a list (or row…) with 8 items are rendered. That's why I wanted to do the "appending" of forms. Would that be possible?

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.