Проблема с сохранением данных динамического набора форм на фронтенде: Даты и время событий не сохраняются
Я столкнулся с проблемой, когда динамические наборы форм (для дат и времени событий) на фронтенде сохраняются некорректно. Форма отображается правильно, новые даты и время событий добавляются динамически с помощью Alpine.js, но при отправке формы данные не сохраняются. Эта проблема не возникает в интерфейсе администратора Django, где наборы форм работают нормально. Я подозреваю, что проблема связана с тем, как данные набора форм обрабатываются на фронтенде. Я использую Django с Alpine.js для обработки наборов форм, и мне нужна помощь в решении проблемы сохранения динамических данных набора форм на фронтенде.
Это мои модели
class EventOption(models.Model):
name = models.CharField(_("Option name"), max_length=100)
amount = models.DecimalField(_("Price"), max_digits=10, decimal_places=2)
slug = AutoSlugField(populate_from='name', unique=True)
published = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = _("Event Option")
verbose_name_plural = _("Event Options")
def __str__(self):
return f"{self.name} - {self.amount}TND"
class Event(models.Model):
name = models.CharField(_("Event name"), max_length=100)
slug = AutoSlugField(populate_from='name', unique=True)
published = models.DateTimeField(auto_now_add=True)
options = models.ManyToManyField(
EventOption, verbose_name=_("Event Options"), blank=True)
amount = models.DecimalField(_("Price"), max_digits=10, decimal_places=2)
description = models.TextField(_("Description"), blank=True, null=True)
class Meta:
verbose_name = _("Event")
verbose_name_plural = _("Events")
def __str__(self):
return self.name
class EventDate(models.Model):
event = models.ForeignKey(
Event, on_delete=models.CASCADE, related_name='event_dates')
date = models.DateField(_("Event date"))
class Meta:
verbose_name = _("Event Date")
verbose_name_plural = _("Event Dates")
def __str__(self):
return self.date.strftime("%d %B %Y")
class EventTime(models.Model):
event_date = models.ForeignKey(
EventDate, on_delete=models.CASCADE, related_name='event_times')
time = models.TimeField(_("Event time"))
maxSubscribers = models.PositiveIntegerField(
_("Max number of subscribers"), default=6)
class Meta:
verbose_name = _("Event Time")
verbose_name_plural = _("Event Times")
ordering = ['time']
constraints = [
models.UniqueConstraint(
fields=['event_date', 'time'], name='unique_event_time')
]
def clean(self):
if self.pk and self.maxSubscribers < self.current_subscriber_count:
raise ValidationError({
'maxSubscribers': _('Max subscribers cannot be less than current subscriber count (%(count)d)')
% {'count': self.current_subscriber_count}
})
@property
def current_subscriber_count(self):
return self.subscribers.count() if hasattr(self, 'subscribers') else 0
def get_available_slots(self):
return max(0, self.maxSubscribers - self.current_subscriber_count)
def is_full(self):
return self.current_subscriber_count >= self.maxSubscribers
def __str__(self):
return f"{self.time.strftime('%H:%M')} ({self.get_available_slots()} places available)"
и это мое мнение
class EventBaseView(LoginRequiredMixin, SuccessMessageMixin):
model = Event
form_class = NewEventForm
template_name = "event/forms/event.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
context['eventdate_formset'] = EventDateFormSet(
self.request.POST, instance=self.object)
for i, date_form in enumerate(context['eventdate_formset']):
prefix = f'time_{i}'
if date_form.instance.pk:
date_form.eventtime_formset = EventTimeFormSet(
self.request.POST, instance=date_form.instance, prefix=prefix)
else:
date_form.eventtime_formset = EventTimeFormSet(
self.request.POST, prefix=prefix)
else:
context['eventdate_formset'] = EventDateFormSet(
instance=self.object)
for i, date_form in enumerate(context['eventdate_formset']):
prefix = f'time_{i}'
if date_form.instance.pk:
date_form.eventtime_formset = EventTimeFormSet(
instance=date_form.instance, prefix=prefix)
else:
date_form.eventtime_formset = EventTimeFormSet(
prefix=prefix)
return context
def form_valid(self, form):
context = self.get_context_data()
eventdate_formset = context['eventdate_formset']
if form.is_valid() and eventdate_formset.is_valid():
self.object = form.save()
eventdate_formset.instance = self.object
eventdates = eventdate_formset.save()
for i, event_date in enumerate(eventdates):
date_form = eventdate_formset.forms[i]
if hasattr(date_form, 'eventtime_formset'):
time_formset = date_form.eventtime_formset
if time_formset.is_bound and time_formset.is_valid():
for time_form in time_formset:
if time_form.is_valid() and time_form.cleaned_data and not time_form.cleaned_data.get('DELETE', False):
time_instance = time_form.save(commit=False)
time_instance.event_date = event_date
time_instance.save()
return super().form_valid(form)
return self.form_invalid(form)
class EventCreateView(EventBaseView, CreateView):
success_url = reverse_lazy('list_event')
success_message = _("Event created successfully.")
class EventUpdateView(EventBaseView, UpdateView):
success_message = _("Event updated successfully.")
def get_success_url(self):
return reverse('update_event', kwargs={'pk': self.object.pk})
мои формы
и мой html