Fix: Order creation error - avoid calling reset_delivery_cost before items are saved
The error occurred because: 1. OrderForm.save(commit=False) was calling reset_delivery_cost() 2. reset_delivery_cost() uses DeliveryCostCalculator which accesses order.items 3. But items don't exist yet when order is not saved to DB Solution: - OrderForm.save() now only calls reset_delivery_cost() when commit=True - order_create() explicitly calls reset_delivery_cost() AFTER saving items - This ensures items exist in DB before delivery cost calculation Error was: 'Order' instance needs to have a primary key value before this relationship can be used.
This commit is contained in:
@@ -200,6 +200,9 @@ class OrderForm(forms.ModelForm):
|
|||||||
Логика:
|
Логика:
|
||||||
- Если delivery_cost заполнено → используется ручное значение (is_custom_delivery_cost = True)
|
- Если delivery_cost заполнено → используется ручное значение (is_custom_delivery_cost = True)
|
||||||
- Если delivery_cost пустое → автоматический расчет (is_custom_delivery_cost = False)
|
- Если delivery_cost пустое → автоматический расчет (is_custom_delivery_cost = False)
|
||||||
|
|
||||||
|
ВАЖНО: reset_delivery_cost() вызывается только при commit=True,
|
||||||
|
т.к. требует наличия сохраненных items в БД.
|
||||||
"""
|
"""
|
||||||
instance = super().save(commit=False)
|
instance = super().save(commit=False)
|
||||||
|
|
||||||
@@ -210,8 +213,12 @@ class OrderForm(forms.ModelForm):
|
|||||||
# Ручное значение указано
|
# Ручное значение указано
|
||||||
instance.set_delivery_cost(delivery_cost, is_custom=True)
|
instance.set_delivery_cost(delivery_cost, is_custom=True)
|
||||||
else:
|
else:
|
||||||
# Пустое поле или 0 → автоматический расчет
|
# Пустое поле или 0 → помечаем что нужен автоматический расчет
|
||||||
instance.reset_delivery_cost()
|
# НО не вызываем reset_delivery_cost() если commit=False!
|
||||||
|
instance.is_custom_delivery_cost = False
|
||||||
|
if commit:
|
||||||
|
# Автоматический расчет только при commit=True
|
||||||
|
instance.reset_delivery_cost()
|
||||||
|
|
||||||
if commit:
|
if commit:
|
||||||
instance.save()
|
instance.save()
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ def order_create(request):
|
|||||||
payment_formset = PaymentFormSet(request.POST)
|
payment_formset = PaymentFormSet(request.POST)
|
||||||
|
|
||||||
if form.is_valid() and formset.is_valid() and payment_formset.is_valid():
|
if form.is_valid() and formset.is_valid() and payment_formset.is_valid():
|
||||||
|
# Сохраняем форму БЕЗ commit, чтобы не вызывать reset_delivery_cost() до сохранения items
|
||||||
order = form.save(commit=False)
|
order = form.save(commit=False)
|
||||||
|
|
||||||
# Обрабатываем адрес доставки
|
# Обрабатываем адрес доставки
|
||||||
@@ -89,6 +90,7 @@ def order_create(request):
|
|||||||
# Кнопка "Создать заказ" - статус из формы или NULL
|
# Кнопка "Создать заказ" - статус из формы или NULL
|
||||||
order.modified_by = request.user
|
order.modified_by = request.user
|
||||||
|
|
||||||
|
# Сохраняем заказ в БД (теперь у него есть pk)
|
||||||
order.save()
|
order.save()
|
||||||
|
|
||||||
# Сохраняем позиции заказа
|
# Сохраняем позиции заказа
|
||||||
@@ -99,6 +101,11 @@ def order_create(request):
|
|||||||
payment_formset.instance = order
|
payment_formset.instance = order
|
||||||
payment_formset.save()
|
payment_formset.save()
|
||||||
|
|
||||||
|
# Пересчитываем стоимость доставки если она не установлена вручную
|
||||||
|
delivery_cost = form.cleaned_data.get('delivery_cost')
|
||||||
|
if not delivery_cost or delivery_cost <= 0:
|
||||||
|
order.reset_delivery_cost()
|
||||||
|
|
||||||
# Пересчитываем итоговую сумму
|
# Пересчитываем итоговую сумму
|
||||||
order.calculate_total()
|
order.calculate_total()
|
||||||
order.save()
|
order.save()
|
||||||
|
|||||||
Reference in New Issue
Block a user