Hey everyone! I’m trying to build a form that will create/update a Model “Recipe”. Inside that Recipe is a many_to_many “RecipeFermentable” which uses a ForeignKey “Fermentable”.
Using basic formsets, I can build it, but I’m having a uber-hard time “saving” this Recipe object or even updating an existing object. I figured I should move to ModelForms. But, I’m not sure how. All examples and docs show 2-levels down (Model-to-Model). However, I’m trying to do Model-to-Model-to-Model.
Here are some snippets:
models.py:
class Recipe(models.Model):
def __str__(self):
return self.name
class Meta:
unique_together = ('name', 'version')
bs_file = models.FileField(storage=fs,null=True)
name = models.CharField(max_length=75)
dateCreated = models.DateField()
notes = models.TextField()
fermentables = models.ManyToManyField(RecipeFermentable)
adjuncts = models.ManyToManyField(RecipeAdjunct)
yeasts = models.ManyToManyField(RecipeYeasts)
class RecipeFermentable(models.Model):
amount_metric = models.FloatField(default=0) # Kilograms / Liters
notes = models.CharField(max_length=200, null=True, blank=True)
fermentable = models.ForeignKey(Fermentable, on_delete=models.RESTRICT)
class Fermentable(RecipeItem):
type = models.ForeignKey(FermentableType,on_delete=models.CASCADE)
sugar_content = models.FloatField() # Brix
class RecipeItem(models.Model):
class Meta:
abstract = True
name = models.CharField(max_length=75)
supplier = models.CharField(max_length=75, null=True, blank=True)
description = models.CharField(max_length=200, null=True, blank=True)
Ergo, Recipe → RecipeFermentable (many) → Fermentable (one)
I’m having a doggone time trying to figure this out. I’ve got my view where I can build a list of Fermentables, in a formset, but it’s a generic formset that I’m having a hard time tying to the actual recipe when saving. It’s all in the same form
Here’s my question. Is the only/best way to do this is using the base formset_factory()? If so, I’ll keep trying my way through it (can’t use ‘instance’). But, was hoping ModelForms could be used to maintain those relationships. I just can’t seem to wrap my head around 3-level model relationships to do it.
It’s highly likely I’m overthinking this. Staring too much at code (tunnel vision)
Current view doesn’t render due to errors, likely because of trying to load instance data the way I’m trying
views.py:
if request.method == "GET":
form = RecipeAddForm()
fermentable_set = formset_factory(FermentableForm)
adjunct_set = formset_factory(AdjunctForm)
yeast_set = formset_factory(YeastForm)
if pk:
# We have a recipe to edit. Load it up
recipe = Recipe.objects.get(pk=pk)
form = RecipeAddForm(initial=model_to_dict(recipe))
fermentable_set = fermentable_set(recipe.fermentables.all().values(),prefix="ferm")
adjunct_set = adjunct_set(recipe.adjuncts.all().values(), prefix="adj")
yeast_set = yeast_set(recipe.yeasts.all().values(), prefix="yeast")
context = {'form': form, 'fermentable_set': fermentable_set,
'adjunct_set': adjunct_set,
'yeast_set': yeast_set}
return render(request, 'batchthis/addRecipe.html', context)