Динамическое добавление/удаление полей DateFields в наборе форм Django

У меня очень специфическая проблема, связанная с пакетом django-bootstrap-datepicker-plus.

В моем приложении Todo list я хочу иметь возможность добавлять задачи на несколько определенных дат. У меня есть модель, есть форма, включая набор форм, и даже есть JavaScript, который обрабатывает динамическую процедуру добавления/удаления.

Проблема заключается в том, что процесс клонирования моих DateField каким-то образом приводит в беспорядок divs DatePicker - см. результат в последнем блоке кода ниже.

# model.py
from django.db import models
from datetime import time

# Create your models here.
class Task(models.Model):

    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=50, default="")
    description = models.CharField(max_length=500, default="")
    entry_date = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    specific_dates = models.ManyToManyField('SpecificDate', blank=True)
    due_until = models.TimeField(auto_now_add=False, default=time(12, 0))


class SpecificDate(models.Model):
    todo = models.ForeignKey(Task, on_delete=models.CASCADE)
    date = models.DateField(auto_now_add=False, blank=True, null=True)

    class Meta:
        # ensure each specific date is unique per task
        unique_together = ('todo', 'date')
# forms.py
from bootstrap_datepicker_plus.widgets import DatePickerInput, TimePickerInput
from django import forms
from .models import Task, SpecificDate

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = [
            'title',
            'description',
            'due_until',
            ]
        widgets = {
            'due_until': TimePickerInput(options={'stepping': 5, 'format': 'HH:mm'}),
            'description': forms.Textarea({'rows': 3}),
        }


class SpecificDateForm(forms.ModelForm):
    class Meta:
        model = SpecificDate
        fields = ['date']
        widgets = {
            'date': DatePickerInput(),
        }


SpecificDateFormset = forms.inlineformset_factory(
    Task, SpecificDate,
    form=SpecificDateForm,
    fields=('date',),
    extra=1,
    can_delete=True
)
<!-- task_form.html -->
{% extends "task/base.html" %}
{% load crispy_forms_tags %}
{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{% block content %}
<div class="content-section">
    <form method="POST">
        {% csrf_token %}
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">New entry</legend>
            {% if form.non_field_errors %}
            <div class="alert alert-danger">
                {{ form.non_field_errors }}
            </div>
            {% endif %}
            {% crispy form %}
            <div id="formset-container">
                {{ formset.management_form }}
                {% for form in formset %}
                    {% if form.errors %}
                    <div class="alert alert-danger">
                        {{ form.errors }}
                    </div>
                    {% endif %}
                    <div id="formset-date" class="formset-date d-flex align-items-center">
                        <div class="flex-grow-1 mr-2">
                            {{ form.date|as_crispy_field }}
                        </div>
                        <div>
                            <button type="button" class="btn btn-sm btn-danger remove-date" name="remove-date">-</button>
                            <button type="button" class="btn btn-sm btn-success add-date" name="add-date">+</button>
                        </div>
                    </div>
                {% endfor %}
            </div>
        </fieldset>
        <div class="form-group">
            <button class="btn btn-primary" type="submit" name="add_new">Save</button>
            <a class="btn btn-warning" href="{% url 'task-new' %}">Restart</a>
        </div>
    </form>
    {{ form.media }}
</div>
{% endblock content %}

HTML-сниппет с набором форм после нажатия кнопки 'add' выглядит следующим образом:

Как вы можете видеть (если посмотрите очень внимательно), свойство dataset.name в DatePicker не обновляется. Точнее, оно обновляется - element.dataset.name имеет правильное имя во время обработки - но в отрисованном HTML оно возвращается к первоначальному имени, и я также получаю эти <input type="hidden" name="null" value=""> элементы.

Вопрос простой: Как я могу получить правильные имена наборов данных в соответствующих полях <input>, чтобы POST запрос при отправке содержал правильные элементы?

Потребовалось несколько итераций, но в итоге я получил рабочий JavaScript-код для решения своей проблемы. Он также позволяет отключить все кнопки добавления/удаления, кроме последней. Это не очень красиво, но работает.

Вернуться на верх