python - Django initial_forms.is_valid() 返回 false
问题描述
我的目标是编辑/更新现有数据。我能够显示现有数据并添加新数据,但不能编辑数据。我的模型是Recipe
和Ingredient
。我modelformset_factory
用来在食谱中添加配料。
这是forms.py:
class RecipeModelForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ('name', )
labels = {
'name': 'Recipe Name'
}
widgets = {
'name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Enter Recipe Name here'
}
)
}
IngredientFormset = modelformset_factory(
Ingredient,
fields=('name', 'amount', 'unit'),
labels={
'name': 'Ingredient Name',
'amount': 'Amount',
'unit': 'Unit'
},
extra=1,
widgets={
'name': forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': 'Enter Ingredient Name here'
}
),
'amount': forms.TextInput(
attrs={
'class': 'form-control',
'placeholder': 'Enter Amount here'
}
),
'unit': forms.Select(
attrs={
'class': 'form-control',
'placeholder': 'Enter Unit here'
}
)
},
can_delete=True
)
视图.py:
@login_required
def update_recipe(request, pk):
template_name = 'recipe/create_with_ingredients.html'
# template_name = 'recipe/update.html'
recipe = Recipe.objects.get(id=pk, author=request.user)
ingredients = Ingredient.objects.filter(recipe=recipe)
if request.method == 'GET':
recipeform = RecipeModelForm(instance=recipe)
formset = IngredientFormset(queryset=ingredients)
elif request.method == 'POST':
recipeform = RecipeModelForm(request.POST, instance=recipe)
formset = IngredientFormset(request.POST, queryset=ingredients)
if recipeform.is_valid(): # and formset.is_valid():
recipe = recipeform.save(commit=False)
recipe.author = request.user
recipe.save()
for form in formset.initial_forms:
print(form.is_valid())
if form.is_valid():
data = form.cleaned_data
for form in formset:
if form.is_valid():
data = form.cleaned_data
if data:
ingredient = form.save(commit=False)
ingredient.recipe = recipe
ingredient.author = request.user
ingredient.save()
return redirect('recipe:list-recipe')
context = {
'recipeform': recipeform,
'formset': formset,
}
return render(request, template_name, context)
我的html模板:
{% extends "recipe/base.html" %}
{% block container %}
{% if heading %}
<h3>{{heading}}</h3>
{% endif %}
<form class="form-horizontal" method="POST" action="">
{% csrf_token %}
<div class="row spacer">
<div class="col-6">
<label>{{recipeform.name.label}}</label>
</div>
<div class="col-8">
<div class="input-group">
{{recipeform.name}}
</div>
</div>
</div>
{{ formset.management_form }}
{% for form in formset %}
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
<!-- {% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %} -->
<div class="row form-row spacer">
<table>
<div class="col-2">
<tr>
<th><label>{{form.name.label}}</label></th>
<th><label>{{form.amount.label}}</label></th>
<th><label>{{form.unit.label}}</label></th>
</tr>
</div>
<div class="col-4">
<tr>
<div class="input-group">
<td>{{form.name}}</td>
<td>{{form.amount}}</td>
<td>{{form.unit}}</td>
<div class="input-group-append">
<td><button class="btn btn-success add-form-row">+</button></td>
</div>
</tr>
</div>
</div>
</table>
</div>
{% endfor %}
<div class="row spacer">
<div class="col-4 offset-0">
<button type="submit" class="btn btn-block btn-primary">Create</button>
</div>
</div>
</form>
{% endblock %}
首先我有if recipeForm.is_valid() and formset.is_valid()
,但这从未导致True
(表单集失败)。因此,我删除了第二次检查,而是验证了表单集中的每个表单。通过这种方法,我发现initial_forms
(现有数据)不在表单集中。因此,为了获得初始表单,我从中得到它,formset.initial_forms
它为我提供了带有编辑数据和现有数据的表单,但是当我调用它时form.is_valid()
它失败了。我不确定为什么初始数据已经在数据库中时无效。如何将已编辑的表单更新为数据库中的现有数据?
解决方案
推荐阅读
- flutter - 当我们在颤动中使用标签栏时如何滚动单个页面?
- javascript - 如何获得垫选择的价值
- javascript - jQuery ajax 工作但 axios 给出 CORS 错误
- graphql - 查询头部分支仍然存在的合并拉取请求
- c - C语言中的Swtich案例问题
- mysql - 当 wordpress 中有数百个子类别时,类别页面主查询加载过多
- facebook-graph-api - Facebook Business Ads Python:访问令牌不同类型的权限
- scala - 如何使用akka测试套件在scala测试中以异步方式获取未来的价值
- php - 从 Wordpress 数据库中检索和显示数据
- javascript - Google Chrome DevTools 无法解析 SourceMap:chrome-extension