我的应用程序有两个模型,Recipe和RecipeIngredient,与外键相关。每个食谱可能有许多不同的食谱成分(每个食谱有不同数量的相关成分)。因此,使用动态formset为配方分配成分似乎是最好的方法。
我有一个简单的表单,用户输入数量并从下拉列表中选择单位和成分。作为一个独立的表单,它可以正常工作。
不幸的是,我无法将任何包含它的formset提交。
我已经在StackOverflow上搜索了许多不同的formset Q& As,但是无法看到问题所在。当我点击提交'时,表单会闪烁并刷新到位,输入的值仍在表单中。没有创建对象。没有错误报告给控制台或浏览器。相关代码:
模特:
class RecipeBase(models.Model):
id = models.UUIDField(primary_key=True,default=uuid.uuid4,null=False)
name = models.CharField(max_length=128,null=False)
creation_date = models.DateField("Record creation date",auto_now_add=True)
creation_user = models.CharField("Record creation user",max_length=150)
lastupdated_date = models.DateField(auto_now=True)
lastupdated_user = models.CharField(max_length=150)
category = models.ForeignKey(RecipeCategory,on_delete=models.CASCADE,related_name='recipes')
subcategory = models.ForeignKey(RecipeSubcategory,on_delete=models.CASCADE,related_name='recipes')
def __str__(self):
return str(self.name)
class RecipeIngredient(models.Model):
id = models.UUIDField(primary_key=True,default=uuid.uuid4,null=False)
quantity = models.DecimalField(max_digits=8,decimal_places=3,null=False)
referenced_unit = models.ForeignKey(UnitDetail,on_delete=models.CASCADE)
referenced_ingredient = models.ForeignKey(Ingredient,on_delete=models.CASCADE)
parent_recipe = models.ForeignKey(RecipeBase,on_delete=models.CASCADE,related_name='ingredients')
def __str__(self):
return str(self.id)[:8]

要求输入成分:
<a class='btn btn-success' href="{% url 'recipes:addingredient' pk=recipe_details.pk %}">Add Ingredients</a>
&#13;
调用视图:
class AddIngredientView(CreateView):
form_class = AddIngredientForm
model = RecipeIngredient
template_name = 'addingredientmultiple2.html'
success_url = "recipes:listrecipes"
def get_context_data(self, **kwargs):
parent_recipe_id = RecipeBase.objects.get(id=self.kwargs['pk'])
data = super(AddIngredientView, self).get_context_data(**kwargs)
if self.request.POST:
data['ingredients'] = AddIngredientFormset(self.request.POST)
data['parent_recipe_id'] = parent_recipe_id
else:
data['ingredients'] = AddIngredientFormset()
data['fixture'] = parent_recipe_id
return data
def form_valid(self, form, **kwargs):
user = self.request.user
fixture = RecipeBase.objects.get(id=self.kwargs['pk'])
context = self.get_context_data()
formset = AddIngredientFormset(self.request.POST)
if formset.is_valid():
ingredients = formset.save()
for recipeingredient in ingredients:
#recipeingredient.creation_user = str(request.user)
#recipeingredient.lastupdated_user = str(request.user)
recipeingredient.parent_recipe_id = parent_recipe_id
#recipeingredient.user = user
recipeingredient.save()
return super(AddIngredientView, self).form_valid(form)
&#13;
使用表单和formset:
class AddIngredientForm(forms.ModelForm):
quantity = forms.DecimalField(widget=forms.NumberInput(attrs={'data-placeholder': 0.00,'size': '8','label_tag': ''}))
referenced_unit = forms.ModelChoiceField(queryset=UnitDetail.objects.all())
referenced_ingredient = forms.ModelChoiceField(queryset=Ingredient.objects.all())
class Meta():
model = RecipeIngredient
fields = ('quantity','referenced_unit','referenced_ingredient',)
AddIngredientFormset = inlineformset_factory(RecipeBase,RecipeIngredient,form=AddIngredientForm,extra=1,can_delete=True)
&#13;
模板:
{{ ingredients.media.css }}
<div class="container">
<h2>Add ingredients to {{ referring_recipe_name }}</h2>
<h4>{{ referring_recipe_id }}</h4>
</div>
<div class="col-md-4">
<form class="form-horizontal" enctype="multipart/form-data" method="post">{% csrf_token %}
<table class="table">
{{ ingredients.management_form }}
{% for form in ingredients.forms %}
{% if forloop.first %}
<thead>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr class="formset_row">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input class='btn btn-success' type="submit" value="Save"/> <a href="{% url 'recipes:listrecipes' %}">back to the list</a>
</form>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="{% static 'formset/jquery.formset.js' %}"></script>
<script type="text/javascript">
$('.formset_row').formset({
addText: 'ADD INGREDIENT',
deleteText: 'REMOVE',
prefix: 'ingredients'
});
</script>
{{ ingredients.media.js }}
&#13;