После прочтения исходного кода для пакета, я считаю, что получение двух запросов на бэкэнд - это нормально.
Ваш код
$(document).ready(function() {
$(".create-shipment").modalForm({
formURL: "{% url 'CreateShipmentView' %}"
});
});
вызывает функцию modalForm
, где он берет ваши параметры (formURL
) и назначает функцию newForm
событию щелчка.
Затем в функции newForm
он вызывает функцию addListeners
, чтобы связать событие щелчка к кнопке отправки в модале, и событие вызывается следующим образом:
isFormValid(modalID, modalContent, modalForm, formURL, errorClass, submitBtn, submitForm);
Обратите внимание, что последний параметр submitForm
указывает на следующую функцию
var submitForm = function(modalForm) {
$(modalForm).submit();
};
Наконец, в Функция isFormValid
, все данные, введенные вами в форму, будут опубликованы по URL-адресу, который вы определили в атрибуте action
для проверки, и если ошибки не будет, форма будет отправлена по тому же URL-адресу.
Если вы покопаетесь в коде python в этом пакете, все станет интересно. BSModalForm
основан на двух классах в mixins.py
и в здесь он говорит, что когда запрос был сделан чем-то отличным от ajax, сохраните экземпляр, созданный с использованием данных формы, или иным образом ( если запрос ajax call), не сохраняйте экземпляр и не возвращайте его. Вот почему она сначала проверяла форму, но никогда не должна сохранять ее (помните, что первый вызов действительно был сделан с помощью вызова ajax в jQuery).
Вы упомянули, что форма сохранялась дважды - попробуйте добавить строку в начале функции сохранения как
print(request.is_ajax())
, а затем проверьте вывод. возможно, что вызов не был отправлен как AJAX вызов. (если это так, обновите вашу версию jquery или используйте что-нибудь еще для совершения вызова, например ax ios)
Если вам не нравится, как идут дела, есть несколько вариантов (пакет под лицензией MIT ):
Измените функцию save
, чтобы проверить экземпляр, затем сохраните его как обычную функцию сохранения django, но для этого потребуется изменить часть кода JS.
Создайте конечную точку API для получения данных и обмена данными, используя json вместо того, чтобы каждый раз возвращать код html (я думаю, это также причина, по которой автор написал JS в текущий путь, потому что тогда вы сталкиваетесь с проблемой рендеринга). Поскольку в настоящее время после отправки формы вам не нужно выполнять никаких других действий, возвращать экземпляр больше не имеет смысла. (нет необходимости в DRF, поскольку в django встроен класс JsonResponse, и если вам нужна только одна конечная точка)
Используйте BootStrap напрямую, поскольку история здесь довольно просто: модальное на странице, кнопка для запуска модального, форма в модальном и вы можете отправить его. Возможно, вам придется написать некоторые свои JS для отображения ошибок, но это все равно должно быть проще, чем изменить существующий пакет.
Пример
# forms.py
from django import forms
# use django ModelForm for creating the form based on model
class CreateShipmentForm(forms.ModelForm):
class Meta:
model = Shipment
fields = ['Reference_Number', 'Ultimate_Consignee']
представление для визуализации формы (GET) и получения отправленных форм (POST)
# views.py
from yourapp.forms import CreateShipmentForm
from django.shortcuts import render
def create_shipment_view(request):
# http POST request means that the form was submitted
if request.method == 'POST':
# create the form and map the data to CreateShipmentForm
shipment_form = CreateShipmentForm(request.POST)
# based on your design of the form/modal, validate the data passed into the form
if shipment_form.is_valid():
# create a new shipment object
new_shipment = shipment_form.save()
# form processing is finished now do something to alert user, for example redirect the user to the success page
return redirect('success')
# if the form is not valid, then shipment_form.errors contain all the errors
else:
# for all other accessing methods including GET
# create an empty form
shipment_form = CreateShipmentForm()
# if the request was POST, the form contains errors, if request was GET, it's an empty form
return render(request, 'path/to/template.html', {
'form': shipment_form
})
Наконец, в своем шаблоне вы можете просто отобразить форму, как обычно. Если вы не знаете или нуждаетесь в каких-либо других функциях для своей формы, продолжайте использовать хрустящие формы.
отметьте if shipment_form.errors
в своем шаблоне и отобразите его в своем шаблоне, если хотите показать ошибки пользователям.