Невозможно заставить кнопки отправки работать с помощью библиотеки django-formset (при нажатии ничего не происходит)
Я использую библиотеку django-formset для разработки программы выставления счетов. Когда я заполняю новую форму и нажимаю кнопку отправки, ничего не происходит. Я изучил документацию и следовал примерам, но безуспешно. Django(5.0.2) и django-formset(1.3.8) обновлены.
У меня есть несколько идей, что может вызвать проблему, и соответствующие вопросы, но я не знаю, как их проверить, поскольку я впервые работаю с css / bootstrap / javascript / typescript (у меня есть только небольшой опыт работы с Python).
- Имеет ли значение, где загружать скрипты - в базовом или дочернем шаблоне?
- Имеет ли значение порядок следования скриптов, и имеет ли значение, где в голове мы загружаем скрипты относительно других элементов?
- Нужно ли перемещать статические файлы из библиотеки formset в папку static в проекте? (Я пробовал копировать-вставлять, но безрезультатно)
Свежий взгляд на это был бы очень признателен, потому что я застрял! У меня такое чувство, что это что-то очень простое, что я упускаю из виду.
models.py:
class Customer(models.Model):
first_name = models.CharField('First Name', max_length=55, blank=True)
last_name = models.CharField('Last Name', max_length=55, blank=True)
phone = models.CharField('Phone Number', max_length=10, blank=True)
alt_phone = models.CharField('Alt Phone Number', max_length=10, blank=True)
company = models.CharField('Company', max_length=55, blank=True)
email = models.EmailField('Email', null=True, blank=True)
address = models.CharField('Address', max_length=55, blank=True)
city = models.CharField('City', max_length=55, blank=True)
state = models.CharField('State', max_length=55, blank=True)
zip = models.CharField('Zip Code', max_length=9, blank=True)
customer_notes = models.TextField('Customer Notes', blank=True)
date_created = models.DateTimeField(auto_created=True, null=True, blank=True)
def __str__(self):
return f'{self.first_name} {self.last_name}'
forms.py:
class CustomerForm(ModelForm):
default_renderer = FormRenderer(
form_css_classes='row border p-1 m-1',
field_css_classes={
'*': 'mb-1 col-4',
'city': 'mb-1 col-3',
'state': 'mb-1 col-1',
'customer_notes': 'mb-1 col-12',
'new': 'mb-5'
},
)
hide_if = 'new_customer.extant'
class Meta:
model = Customer
fields = [
'first_name',
'last_name',
'company',
'phone',
'alt_phone',
'email',
'address',
'city',
'state',
'zip',
'customer_notes',
]
widgets = {
'first_name': forms.TextInput(attrs={
'class': 'form-control',
'id': 'first_name',
'placeholder': 'Customer First Name',
}),
'last_name': forms.TextInput(attrs={
'class': 'form-control',
'id': 'last_name',
'placeholder': 'Customer Last Name',
}),
'phone': forms.NumberInput(attrs={
'class': 'form-control',
'id': 'phone',
}),
'alt_phone': forms.NumberInput(attrs={
'class': 'form-control',
'id': 'alt_phone',
}),
'company': forms.TextInput(attrs={
'class': 'form-control',
'id': 'company',
}),
'email': forms.EmailInput(attrs={
'class': 'form-control',
'id': 'email',
}),
'address': forms.TextInput(attrs={
'class': 'form-control',
'id': 'address',
}),
'city': forms.TextInput(attrs={
'class': 'form-control',
'id': 'city',
}),
'state': forms.TextInput(attrs={
'class': 'form-control',
'id': 'state',
'value': 'CA',
}),
'zip': forms.TextInput(attrs={
'class': 'form-control',
'id': 'zip',
}),
'customer_notes': forms.Textarea(attrs={
'class': 'form-control',
'id': 'customer_notes',
'placeholder': 'Enter customer notes',
'rows': '1'
}),
'date_created': forms.DateTimeInput(attrs={
'class': 'form-control',
'id': 'date_created',
'value': datetime.now()
})
}
views.py:
class EditView(UpdateView, FormViewMixin):
def get_object(self, queryset=None):
if self.extra_context['add'] is False:
return super().get_object(queryset)
def form_valid(self, form):
if extra_data := self.get_extra_data():
if extra_data.get('delete') is True:
self.object.delete()
success_url = self.get_success_url()
response_data = {'success_url': force_str(success_url)} if success_url else {}
return JsonResponse(response_data)
return super().form_valid(form)
class CustomerEditView(EditView):
model = Customer
template_name = 'invoice/customer-add.html'
form_class = CustomerForm
extra_context = None
def get_success_url(self):
if pk := self.object.id:
return reverse('customer-edit', kwargs={'pk': pk})
else:
return reverse('customer-list')
urls.py
urlpatterns = [
path('customers', CustomerListView.as_view(), name='customer-list'), # list view not handled here
path('customer/add/', CustomerEditView.as_view(extra_context={'add': True}), name='customer-add', ),
path('customer/<int:pk>/', CustomerEditView.as_view(extra_context={'add': False}), name='customer-edit', ),
]
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Invoice Management</title>
<!-- bootstrap5 css -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<link href="{% static '/css/sb-admin-2.css' %}" rel="stylesheet"></link>
<link href="{% static '/css/style.css' %}" rel="stylesheet">
<!-- FONT AWESOME -->
<script src="https://kit.fontawesome.com/016d1bf7c0.js" crossorigin="anonymous"></script>
<!-- bootstrap5 javascript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
crossorigin="anonymous"></script>
<!-- django-formset -->
<script type="module" src="{% static 'formset/js/django-formset.js' %}"></script>
{% block head_script %}
{% endblock %}
</head>
<div class="card w-100 shadow my-2">
{% block content %}{% endblock %}
</div>
customer-add.html
{% extends "invoice/base/base.html" %}
{% load i18n %}
{% load static %}
<!-- Content Row -->
{% block content %}
<!-- CUSTOMER FORM -->
<div id="customer-info" class="card-body collapse show">
{% load render_form from formsetify %}
<django-formset endpoint="{{ request.path }}" csrf-token="{{ csrf_token }}">
{% render_form form %}
{% if add %}
<button type="button" df-click="submit({add: true}) -> proceed">{% trans "Add" %}</button>
{% else %}
<button type="button" df-click="submit({update: true}) -> proceed">{% trans "Update" %}</button>
<button type="button" df-click="submit({delete: true}) -> proceed">{% trans "Delete" %}</button>
{% endif %}
</django-formset>
</div>
{% endblock %}