首页 > 解决方案 > Django initial_forms.is_valid() 返回 false

问题描述

我的目标是编辑/更新现有数据。我能够显示现有数据并添加新数据,但不能编辑数据。我的模型是RecipeIngredient。我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()它失败了。我不确定为什么初始数据已经在数据库中时无效。如何将已编辑的表单更新为数据库中的现有数据?

标签: pythondjangodjango-forms

解决方案


首先尝试检查表单验证错误。

  • 这个答案可能会帮助你做到这一点,
  • 如果没有,请检查文档。

如果我的解决方案还不够,请向我们提供带有错误消息的额外反馈。


推荐阅读