def magic_handle_form(Class, Class_form, request, instance=None): return magic_handle_inlineformsets(Class, Class_form, request, {}, instance) def magic_handle_inlineformsets(Class, Class_form, request, inline_formset_dict, instance=None): """ give me a main Class (Recipe), ClassForm (RecipeForm) and maybe Instance (recipe), the request and a inline_formset_dict like: { "recipe_ingredients":IngredientsRecipeFormSet, "recipe_inline2": Inline2RecipeFormSet } and you get back a formset_dict you can iterate through in template, "_formset" will be appended to keys or a success with a dict of the saved model instances, "obj" will be key for main model """ formset_dict = {} dont_save = False got_post = request.method == 'POST' result = {} if got_post: class_form = Class_form(request.POST, instance=instance) if instance else Class_form(request.POST) if class_form.is_valid(): obj = class_form.save(commit=False) for key,form in inline_formset_dict.items(): formset_dict[key+"_formset"] = form(request.POST, request.FILES, instance=obj) if not formset_dict[key+"_formset"].is_valid(): dont_save = True if dont_save: result = {"form":class_form} result.update(formset_dict) return result else: obj.save() class_form.save_m2m() new_objs_dict = {} for key,form in formset_dict.items(): new_objs_dict[key.rsplit("_formset",1)[0]] = form.save() if hasattr(form, "save_m2m"): form.save_m2m() result = {"obj":obj} result.update(new_objs_dict) return result if instance: obj = instance else: obj = Class() class_form = Class_form(request.POST, request.FILES, instance=obj) if got_post else Class_form(instance=obj) for key,form in inline_formset_dict.items(): formset_dict[key+"_formset"] = form(request.POST, request.FILES, instance=obj) if got_post else form(instance=obj) result = {"form":class_form} result.update(formset_dict) return result ######################### EXAMPLE USE ########################## in views.py def add_edit_recipe(request, recipe_id=None, template_name='recipe.html'): _recipe= None used_form = RecipeAddForm if recipe_id: # we want to edit a recipe _recipe = get_obj_from_site_or_404(Recipe, pk=recipe_id) used_form = RecipeEditForm #we want an other form for editions inline_formsets = {"ingredient":IngredientRecipeFormSet, "image":ImageRecipeFormSet} result = magic_handle_inlineformsets(Recipe, used_form, request, inline_formsets, instance=_recipe) if result.has_key("obj") and isinstance(result["obj"], Recipe): # so the Recipe is now saved and we can continue somewhere else next = reverse('recipes') return HttpResponseRedirect(next) ctx = {} #kick the forms into the context ctx.update(result) context = RequestContext(request, ctx) return render_to_response(template_name, context_instance=context)