Наборы форм вложенных моделей Django сохраняют только первую форму
У меня есть два набора форм, которые я создал с помощью modelsetfactory. Когда я задаю дополнительное поле вручную, он сохраняет все формы. Но когда я добавляю форму динамически, сохраняется только первая форма. До использования вложенных наборов форм я не сталкивался с такой ошибкой, но мне пришлось перепроектировать первую форму как набор форм.
Как видно на рисунке, он сохраняет только первую из форм, которые я добавляю динамически. Сохраняет "Тестовый продукт", но не "Тестовый продукт 2"
вот мои модели :
class UserTask(models.Model):
id = models.AutoField(primary_key=True)
user_id = models.ForeignKey(User,on_delete= models.CASCADE, verbose_name='User',null=True, related_name="user_id")
task_types_id = models.ForeignKey(TaskTypes,on_delete=models.CASCADE,verbose_name="Task Type", default=None)
subunit_id = models.ForeignKey(WorksiteSubunit,on_delete= models.CASCADE,verbose_name="Subunit",null=True, default=None)
store_house_id = models.ForeignKey(StoreHouse,on_delete= models.CASCADE,verbose_name="Store House",null=True)
description = models.TextField(max_length=255)
author = models.ForeignKey(User,on_delete= models.CASCADE,null=True, related_name="author_id")
class TaskSources(models.Model):
id = models.AutoField(primary_key=True)
user_task_id = models.ForeignKey(UserTask,on_delete=models.CASCADE)
product_id = models.ForeignKey(Product,on_delete=models.CASCADE,verbose_name="Product",null=True)
product_amount = models.FloatField(max_length=255,verbose_name="Product Amount",null=True)
def __str__(self):
return str(self.user_task_id.store_house_id)
вот мои формы :
class UserTaskForm(forms.ModelForm):
class Meta:
model = UserTask
fields = ['user_id','task_types_id','store_house_id','description']
class TaskSourcesForm(forms.ModelForm):
class Meta:
model = TaskSources
fields = ['product_id', 'product_amount']
TaskSourcesFormSet = modelformset_factory(
TaskSources,
fields=('product_id', 'product_amount',),
extra=1,
)
UserTaskFormFormSet = modelformset_factory(
UserTask,
fields=('user_id','task_types_id','store_house_id','description',),
extra=1,
)
вот мои взгляды :
@login_required(login_url="login")
def addUserTask(request):
user_task_form = UserTaskFormFormSet(queryset=UserTask.objects.none(),initial=[{'user_id': request.user}])
formset = TaskSourcesFormSet(queryset=TaskSources.objects.none())
if request.method == 'POST':
user_task_form = UserTaskFormFormSet(request.POST)
formset = TaskSourcesFormSet(request.POST)
if user_task_form.is_valid():
for form in user_task_form:
if form.has_changed():
user_task = form.save(commit=False)
user_task.author = request.user
user_task.save()
if formset.is_valid():
for form_data in formset:
task_sources = form_data.save(commit=False)
task_sources.user_task_id = UserTask(id = user_task.id)
task_sources.save()
messages.success(request,"Task added successfully!")
return redirect(".")
context = {
"user_task_form" : user_task_form,
"formset" : formset,
}
return render(request,"user/addtask.html",context)
и вот мой html :
{% extends "main/layout.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="col-md-6 offset-md-3">
<h3 align="center">Add New Task</h3>
<hr>
<form id="form-container" method="POST">
{% csrf_token %}
{{ user_task_form.management_form }}
{% for user_form in user_task_form %}
<div class="usertask-form" id="usertask-form">
{{user_form | crispy}}
</div>
{% endfor %}
{{ formset.management_form }}
{% for form in formset %}
<div class="tasksources-form" id="tasksources-form">
{{form | crispy}}
</div>
{% endfor %}
<button id="add-form" class="btn btn-success">+Add More Product</button>
<br>
<br>
<button type="submit" class="btn btn-outline-info">Add New Task</button>
</form>
</div>
</div>
<script>
let tasksourcesForm = document.querySelectorAll(".tasksources-form")
let container = document.querySelector("#form-container")
let addButton = document.querySelector("#add-form")
let totalForms = document.querySelector("#id_form-TOTAL_FORMS")
let formNum = tasksourcesForm.length-1
addButton.addEventListener('click', addForm)
function addForm(e){
e.preventDefault()
$('select').select2("destroy");
let newForm = tasksourcesForm[0].cloneNode(true)
let formRegex = RegExp(`form-(\\d){1}-`,'g')
formNum++
newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form-${formNum}-`)
container.insertBefore(newForm, addButton)
totalForms.setAttribute('value', `${formNum+1}`)
$('select').select2({
allowClear: true
});
}
</script>
{% endblock content %}
Что является причиной этого? В чем заключается ошибка в архитектуре?