Массовое создание элементов в Django CreateView

Я хотел бы попробовать добавить строки в шаблон, а затем сохранить его. В шаблоне нажмите кнопку "Добавить строки", чтобы создать новую строку, и "отправить" сохранить эту форму. Что я хочу сделать, так это то, что пользователь может добавить номер строки и сохранить его. Но в CreateView всегда есть только первый ряд. Я пробовал много способов, но до сих пор не знаю.

Например, у меня есть первый ряд

<th><input type="checkbox" name="record"></th>
<th><p id="counter"> 1 </p></th>
<th><input type="number" name="quantity" step="any" required id="id_quantity"></th>

после нажатия кнопки "добавить" следующий HTML-код будет добавлен после первой строки

<th><input type="checkbox" name="record"></th>
<th><p id="counter"> 1 </p></th>
<input type="number" name="quantity-2" step="any" required="" id="id_quantity-2">

Вот мой шаблон:

<form method="post" class="uniForm" action="">
    {% csrf_token %}
    <table class="table table-striped table-condensed" id="dyeing">
        <thead>
        <tr>
            <th>choice</th>
            <th>number</th>
            <th>ticket</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <th><input type="checkbox" name="record"></th>
            <th><p id="counter"> 1 </p></th>
            <th>...</th>
        </tr>
        </tbody>
    </table>
    <div class="col-sm-12">
        <input type="button" id="btn" value="add"/>
    </div>
    <div class="col-sm-12">
        <input type="submit" value=" save" class="">
    </div>
</form>

и часть jQuery:

<script>
$("#btn").click(function () {
    //var markup = "<tr><td><input type='checkbox' name='
    addrow($('#dyeing > tbody:last-child'))
});

function addrow(selector) {
    new_row = selector.clone(true)
    counter = parseInt(new_row.find('#counter').text(), 10) + 1
    new_row.find(":input").each(function () {
        var name = $(this).attr('name');
        if (counter == 2) {
            name = name + '-' + counter
        } else {
            name.replace('-' + (counter - 1), '-' + counter)
        }

        var id = 'id_' + name;
        $(this).attr({'name': name, 'id': id})
    })

    new_row.find('#counter').text(counter)
    selector.after(new_row)
    counter++
}

мои views.py:

class CreateTicketForm(generic.CreateView):
...

def form_valid(self, form):
    # only get the first row
    print(form)
    return super().form_valid(form)

1 ответ

Решение

Ответь на вопрос для себя. Вот код form.py:

class TicketForm(forms.ModelForm):
    class Meta:
        model = ...
        fields = "color"

views.py:

def create_ticket(request):
    ...
    if request.method == "POST":
        forms = [
            TicketForm(dict(color=c, ))
            for c, q, n in zip(
                request.POST.getlist("color"),
            )
        ]
        if all(forms[i].is_valid() for i in range(len(forms))):
            for form in forms:
                form.save()
            return HttpResponseRedirect(success_url)
    else:
        form = TicketForm()

    return render(request, 'template', {'form': form})

и часть jQuery:

$("#btn").click(function () {
        addrow($('#dyeing > tbody:last-child'))
    });

    function addrow(selector) {
        var new_row = selector.clone(true)
        var counter = parseInt(new_row.find('#counter').text(), 10) + 1
        new_row.find('#counter').text(counter)
        selector.after(new_row)
    }
Другие вопросы по тегам