Source Data for Django Embedded Forms

I put together a form to save the recipe. It uses a form and an integrated set of forms. I have users with text files containing recipes, and they would like to cut and paste the data to make recording easier. I have developed how to fill out part of the form after processing the original text input, but I cannot figure out how to fill out the inline set of forms.

It seems like the solution is almost spelled out here: http://code.djangoproject.com/ticket/12213 , but I can’t completely compose the fragments.

My models:

#models.py from django.db import models class Ingredient(models.Model): title = models.CharField(max_length=100, unique=True) class Meta: ordering = ['title'] def __unicode__(self): return self.title def get_absolute_url(self): return self.id class Recipe(models.Model): title = models.CharField(max_length=255) description = models.TextField(blank=True) directions = models.TextField() class Meta: ordering = ['title'] def __unicode__(self): return self.id def get_absolute_url(self): return "/recipes/%s/" % self.id class UnitOfMeasure(models.Model): title = models.CharField(max_length=10, unique=True) class Meta: ordering = ['title'] def __unicode__(self): return self.title def get_absolute_url(self): return self.id class RecipeIngredient(models.Model): quantity = models.DecimalField(max_digits=5, decimal_places=3) unit_of_measure = models.ForeignKey(UnitOfMeasure) ingredient = models.ForeignKey(Ingredient) recipe = models.ForeignKey(Recipe) def __unicode__(self): return self.id 

A recipe form is created using ModelForm:

 class AddRecipeForm(ModelForm): class Meta: model = Recipe extra = 0 

And the corresponding code in the view (calls to parse form inputs are deleted):

 def raw_text(request): if request.method == 'POST': ... form_data = {'title': title, 'description': description, 'directions': directions, } form = AddRecipeForm(form_data) #the count variable represents the number of RecipeIngredients FormSet = inlineformset_factory(Recipe, RecipeIngredient, extra=count, can_delete=False) formset = FormSet() return render_to_response('recipes/form_recipe.html', { 'form': form, 'formset': formset, }) else: pass return render_to_response('recipes/form_raw_text.html', {}) 

With FormSet () empty as above, I can successfully launch the page. I tried several ways to feed a set of forms with the quantity, unit of measurability, and the ingredients that I identified, including:

  • setting the initial data, but this does not work for inline forms.
  • dictionary submission but which generates control form errors
  • played with init , but I'm a bit out of depth.

Any suggestions that were highly appreciated.

+6
python django forms inline-formset
source share
2 answers

My first suggestion would be to make a simple way out: save the Recipe and RecipeIngredient s, and then use the resulting Recipe as your instance when creating the FormSet . You might want to add a β€œverified” boolean field to your recipes to indicate whether these forms were then approved by the user.

However, if you do not want to follow this road for any reason, you must fill out your forms as follows:

We will assume that you have analyzed the text data in the recipe ingredients and have a list of dictionaries like this:

 recipe_ingredients = [ { 'ingredient': 2, 'quantity': 7, 'unit': 1 }, { 'ingredient': 3, 'quantity': 5, 'unit': 2 }, ] 

The numbers in the "ingredient" and "unit" fields are the primary key values ​​for the respective ingredients and units. I assume that you have already formulated some way of matching text with ingredients in your database or creating new ones.

Then you can:

 RecipeFormset = inlineformset_factory( Recipe, RecipeIngredient, extra=len(recipe_ingredients), can_delete=False) formset = RecipeFormset() for subform, data in zip(formset.forms, recipe_ingredients): subform.initial = data return render_to_response('recipes/form_recipe.html', { 'form': form, 'formset': formset, }) 

This sets the initial property of each form in the form set to the dictionary from your recipe_ingredients list. This seems to work for me in terms of displaying a set of forms, but I have not tried to save yet.

+19
source share

I couldn't get Aram Dulyan code to work on this

 for subform, data in zip(formset.forms, recipe_ingredients): subform.initial = data 

Apparently, something has changed on django 1.8 that I cannot iterate over property caching

forms - django.utils.functional.cached_property object at 0x7efda9ef9080

I got this error

zip # 1 argument must support iteration

But I still take the dictionary and assign it directly to my set of forms, and it worked, I took an example from here:

https://docs.djangoproject.com/en/dev/topics/forms/formsets/#understanding-the-managementform

from django.forms import formset_factory from myapp.forms import ArticleForm

 ArticleFormSet = formset_factory(ArticleForm, can_order=True) formset = ArticleFormSet(initial=[ {'title': 'Article #1', 'pub_date': datetime.date(2008, 5, 10)}, {'title': 'Article #2', 'pub_date': datetime.date(2008, 5, 11)}, ]) 

My code for assigning a pattern to a pattern

 return self.render_to_response( self.get_context_data(form=form, inputvalue_numeric_formset=my_formset(initial=formset_dict) 
0
source share

All Articles