Django сложные многоформные представления
Я не так хорош в кодинге, так что будьте проще. Я хочу создать/обновить представление с несколькими моделями в одной форме, но мне нужно динамически добавлять вторую и третью модель (нужны наборы форм) в представление. Этого можно добиться с помощью javascript, копируя пустые формы.
здесь структура модели, нужно, чтобы она была масштабируемой, но давайте уложим ее в 3 модели.
Что мне нужно
1) представить родительскую и вторую 2) нажать кнопку resolve, которая отправит ajax и все данные формы, затем я обрабатываю validate и получаю дополнительные данные, которые генерируют третью форму 3) сохранить все обратно в базу данных, с соответствующими ForeigKeys между моделями
models.py
from django.db import models
class Parrent(models.Model):
data = models.CharField(max_length=30)
class Second(models.Model):
parent = models.ForeignKey(Parrent, on_delete=models.CASCADE)
data = models.CharField(max_length=30)
class Third(models.Model):
second = models.ForeignKey(Second, on_delete=models.CASCADE)
data = models.CharField(max_length=30)
forms.py
from django.forms import ModelForm
from myapp.models import Parrent, Second, Third
class ParrentForm(ModelForm):
class Meta:
model = Parrent
fields = ['data']
class SecondForm(ModelForm):
class Meta:
model = Second
fields = ['data']
class ThirdForm(ModelForm):
class Meta:
model = Third
fields = ['data']
SecondFormSet = formset_factory(SecondForm, extra=1)
ThirdFormSet = formset_factory(ThirdForm, extra=1)
template.html
<!-- [ Template form second] start -->
<div id='template-second-form' class="card-body table-border-style hidden">
{{ forms.second}}
<br>
<button type="button" class="btn btn-danger delete_btn">Remove</button>
</div>
<!-- [ Template volume ] end -->
<!-- [ repeated for the third ] end -->
<!-- [ FORM ] start -->
<form id='multi-form' method="post">{% csrf_token %}
<div class="card-body table-border-style">
{{ forms.parrent}}
</div>
<!-- [ Second list ] start -->
<div id='second-list'>
<!-- [ list all second elements here (javascript) ] -->
</div>
<!-- [ Second list ] end -->
<div class="card-body table-border-style">
<button id='add-second'type="button" class="btn btn-primary">Add second</button>
<button id='resolve'type="button" class="btn btn-info">Resolve</button>
</div>
test.js
const addNewSecondBtn= document.getElementById('add-second')
addNewSecondBtn.addEventListener('click', add_new_second_form)
function add_new_second_form(event) {
if (event) {
event.preventDefault()
}
// add new empty form element to html form
const emptySecondFormEl = document.getElementById('template-second-form').cloneNode(true)
emptySecondFormEl.classList.remove('hidden')
const VolumeListEl = document.getElementById('second-list')
VolumeListEl.append(emptyVolumeFormEl)
}
document.addEventListener('click', ({target: btn})=>{
btn.matches('.delete_btn') && btn.parentNode.remove()
}, false);
$(document).ready(function() {
$("#resolve").click(function () {
var serialData = $("#multi_form").serializeArray()
serialData = JSON.stringify(serialData);
console.log(serialData)
$.ajax({
type: "GET",
url: "/ajax/resolve/",
data: {
serialData: serialData,
},
success: function () {
console.log("done");
},
error: function () {
console.log("error");
},
});// & ajax
});
}) //$ doc ready func
Я хотел бы использовать представление на основе классов, я просмотрел типовые представления, но кажется, что они недостаточно вменяемы, чтобы понять, какую функцию я должен вручную отредактировать, чтобы заставить ее работать. Также проверил некоторые сторонние модули, такие как better-forms -> не уверен, как вписать наборы форм внутрь и кажется устаревшим (работает на django4) и multiform -> обрабатывает формы отдельно, а мне нужна одна форма. Crypsi forms выглядит просто для стилизации. Я рассматривал inline formset, но не уверен, как вместить более двух моделей, поскольку всегда есть пример только для двух.