Обновление Django Formsets с данными о поле many_to_many
Мне кажется, что я исчерпал весь свой гугл-фу по этому вопросу. Я перепробовал столько разных способов, что не могу вспомнить, что именно пробовал.
У меня есть класс "Recipe", который имеет 3 поля many_to_many. У меня есть пустая форма, использующая наборы форм для каждого объекта many_to_many для new.
Сейчас я модифицирую форму, чтобы включить "update", но я не могу заставить формообразующий набор заполнить данные. Я пробовал "instance=", я пробовал передавать словарь "model_to_dict", но я не могу разобраться с этим. Моя текущая итерация выглядит следующим образом:
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()
dateUpdated = models.DateField(null=True, blank=True)
version = models.IntegerField(null=True, blank=True)
#type = models.CharField(max_length=30) #Cider, Mead, Wine, etc
category = models.ForeignKey(BatchCategory,on_delete=models.CASCADE)
brewer = models.CharField(max_length=30, null=True)
batchSize = models.FloatField() #in Liters
source = models.CharField(max_length=50, null=True) #Where did the recipe come from
pairing = models.CharField(max_length=250, null=True) # Textfield listing various foods. TODO: Refactor
notes = models.TextField()
estOG = models.FloatField()
estFG = models.FloatField()
estABV = models.FloatField()
fermentables = models.ManyToManyField(RecipeFermentable)
adjuncts = models.ManyToManyField(RecipeAdjunct)
yeasts = models.ManyToManyField(RecipeYeasts)
Вы можете видеть мои 3 поля many_to_many внизу.
views.py:
def addRecipe(request,pk=None):
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)
else:
form = RecipeAddForm(request.POST)
fermentable_set = formset_factory(FermentableForm)
if form.is_valid() and fermentable_set.is_valid():
recipe = Recipe()
data = form.cleaned_data
recipe.name = data['recipe_name']
recipe.dateCreated = data['date_created']
recipe.dateUpdated = data['date_updated']
recipe.brewer = data['brewer']
recipe.batchSize = data['batch_size']
recipe.notes = data['notes']
recipe.estOG = data['estOG']
recipe.estFG = data['estFG']
recipe.estABV = data['estABV']
category = BatchCategory.objects.get(pk=data['category'])
recipe.category = category
recipe.save()
#TODO Add Fermentable Formset
fermentables = []
adjuncts = []
yeasts = []
for form_item in fermentable_set:
fermentable = RecipeFermentable()
fermentable.amount = form_item.cleaned_data.get('amount_metric')
fermentable.fermentable = form_item.cleaned_data.get('fermentable')
fermentable.intended_use = form_item.cleaned_data.get('intended_use')
fermentable.is_fermentable = form_item.cleaned_data.get('is_fermentable')
fermentable.save()
fermentables.append(fermentable)
#TODO Add Adjuncts Formset
#TODO Add Yeasts Formset
recipe.fermentables.set(fermentables)
print("Returning response using Recipe PK of " + str(recipe.pk))
return HttpResponseRedirect(reverse('recipe', kwargs={'pk': recipe.pk}))
else:
return render(request, 'batchthis/addRecipe.html', {'form': form})
Чтобы быть кратким, я приведу фрагмент моего шаблона.
addRecipe.html:
<div class = "col-md-6 col-mb-0">
{{ form.notes|as_crispy_field }}
</div>
</div>
{{ fermentable_set.management_form }}
<div id="fermentable_form_set">
{% for fermentable_form in fermentable_set %}
<div id="fermentable_form" class = "form-group row border-left-primary">
<div class = "col-md-4 col-mb-0">
{{ fermentable_form.fermentable|as_crispy_field }}
</div>
<div class = "col-md-2 col-mb-0">
{{ fermentable_form.amount_metric|as_crispy_field }}
</div>
<div class = "col-md-2 col-mb-0">
{{ fermentable_form.amount_unit|as_crispy_field }}
</div>
<div class = "col-md-2 col-mb-0">
{{ fermentable_form.intended_use|as_crispy_field }}
</div>
<div class = "col-md-2 col-mb-0">
{{ fermentable_form.is_fermentable|as_crispy_field }}
</div>
</div>
{% endfor %}
</div>
<input type="button" class="btn btn-secondary" value = "Add Fermentable" id="addFermentableFormButton">
{{ adjunct_set.management_form }}
<div id="adjunct_form_set">
{% for adjunct_form in adjunct_set %}
<div id="adjunct_form" class = "form-group row border-left-success">
<div class = "col-md-4 col-mb-0">
{{ adjunct_form.adjunct|as_crispy_field }}
</div>
Моя текущая итерация жалуется на мою {{ fermentable_set.managementform }}.
слишком много значений для распаковки (ожидалось 2)
Это может быть открытый вопрос, но моя цель - заполнить мои наборы форм объектами many_to_many, назначенными Recipe. Есть какие-нибудь мысли? Заранее спасибо!