Django динамически добавляемые формы - '<' не поддерживается между экземплярами 'NoneType' и 'int
В настоящее время я создаю сайт на Django, который позволяет пользователю вводить детали рецепта, который он хочет создать и сохранить. Это означает, что пользователь должен иметь возможность динамически добавлять поля formset для таких вещей, как ингредиенты и шаги рецепта.
Я реализовал способ динамического добавления этих полей с помощью Javascript, но в настоящее время он работает только с can_delete_extra и can_delete в наборе форм, установленными в False, что мне нужно изменить, потому что а) я не хочу, чтобы флажок удаления отображался в наборе форм при создании рецепта (я искал способ скрыть это, но безуспешно) и б) пользователю нужно иметь возможность удалить ненужные поля при последующем редактировании рецепта.
Сообщение об ошибке, которое я получаю: '<' not supported between instances of 'NoneType' and 'int', occurring in: Desktop\recipe_site\recipe_env\lib\site-packages\django\forms\formsets.py, line 416, in add_fields.
Ниже приведен мой код. Javascript основан на this post.
create_recipe.html
<h2>Ingredients</h2>
{{ iformset.management_form }}
<div id=ingredientform>
{% for i_form in iformset %}
<div class = ingredientinfo>
{{ i_form.as_p }}
</div>
{% endfor %}
</div>
<input type="button" value="Add More" id="add_more_ingredients">
<script>
let ingFormCount = {{ iformset.total_form_count }}
let emptyIngForm = '{{ iformset.empty_form.as_p|escapejs }}'
</script>
<script src="{% static 'recipes/add_more_ingredients.js' %}"></script>
<
let addIngButton = document.querySelector("#add_more_ingredients")
addIngButton.addEventListener('click', addIngForm)
function addIngForm(e) {
e.preventDefault()
ingFormCount++
// Update the management form to use the correct value of TOTAL_FORMS
// to allow extra forms to be saved.
let totalForms = document.getElementById("id_ingredients-TOTAL_FORMS")
totalForms.setAttribute('value', ingFormCount+1)
let ingredientForm = document.querySelector("#ingredientform")
let ingContainer = document.createElement('div');
ingContainer.classList.add('ingredientinfo');
ingContainer.insertAdjacentHTML("beforeend", emptyIngForm.replace(/__prefix__/g, ingFormCount))
ingredientForm.appendChild(ingContainer)
models.py
class Ingredient(models.Model):
ingredient_name = models.CharField(max_length=50)
quantity = models.CharField(max_length=50)
recipe = models.ForeignKey(
RecipeCard, on_delete=models.CASCADE, related_name="ingredients")
def __str__(self):
return self.ingredient_name
forms.py
class IngredientForm(forms.ModelForm):
class Meta:
model = Ingredient
exclude = ['recipe',]
IngredientFormSet = inlineformset_factory(
RecipeCard,
Ingredient,
form = IngredientForm,
can_delete_extra = False,
can_delete = True,
extra=2,
max_num=15)
Похоже, что проблема заключается в следующей функции из исходного кода Django formset:
def add_fields(self, form, index):
"""A hook for adding extra fields on to each form instance."""
if self.can_order:
# Only pre-fill the ordering field for initial forms.
if index is not None and index < self.initial_form_count():
Насколько я могу судить (я не очень опытен), ошибка возникает потому, что в моем коде index
выше стоит None. Я просмотрел остальной исходный код набора форм и также нашел следующее, что, как мне показалось, может иметь значение, поскольку в моем шаблоне тег <script>
генерирует пустую форму:
def get_form_kwargs(self, index):
"""
Return additional keyword arguments for each individual formset form.
index will be None if the form being constructed is a new empty
form.
"""
return self.form_kwargs.copy()
Буду признателен за помощь в решении этой проблемы, если она может быть решена путем изменения моего кода или переопределения Django каким-либо образом - или если вы думаете, что существует лучший метод реализации динамического добавления формы в Django. Большое спасибо.
вы можете дать индексу значение по умолчанию, например
def add_fields(self, form, index=7):
и выберите значение по умолчанию в соответствии с тем, что должно произойти, если значение не указано.