If you read the docstring and the example you should get a clue what this Code does. I didn't want a big function everytime that handles every specific form, formset combinations so this how i can add/edit Models with specific Forms given to the magic_handle_inlineformsets function. It also works for Forms without innline_formsets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 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)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.