Django Form Submission Not Triggering `create_cancel` View
Описание проблемы:
Я реализую функцию отмены заказа в своем Django-приложении. Процесс включает отображение формы отмены заказа (cancel-order.html
) с помощью представления cancel_order
и обработку отправки формы с помощью представления create_cancel
для обновления product_status
в CartOrder
и CartOrderItems
.
Однако проблема заключается в том, что представление create_cancel
не запускается при отправке формы. Не отображаются сообщения об успехе или ошибке, и не происходит обновления базы данных.
Виды: Вот соответствующие виды:
def cancel_order(request, oid):
sub_category = SubCategory.objects.all()
categories = Category.objects.prefetch_related('subcategories').order_by('?')[:4]
wishlist = wishlist_model.objects.filter(user=request.user) if request.user.is_authenticated else None
nav_category = Category.objects.filter(special_category=True).prefetch_related('subcategories').order_by('?')[:4]
order = CartOrder.objects.get(user=request.user, id=oid)
products = CartOrderItems.objects.filter(order=order)
# Calculate discounts for each product
total_old_price = 0
total_price = 0
for item in products:
product = item.product # Assuming a ForeignKey from CartOrderItems to Product
qty = item.qty # Assuming a quantity field in CartOrderItems
total_old_price += (product.old_price or 0) * qty
total_price += (product.price or 0) * qty
# Calculate total discount percentage
if total_old_price > 0: # Prevent division by zero
discount_percentage = ((total_old_price - total_price) / total_old_price) * 100
else:
discount_percentage = 0
context = {
"order": order,
"products": products,
"sub_category": sub_category,
"categories": categories,
"wishlist": wishlist,
"nav_category": nav_category,
"discount_percentage": round(discount_percentage, 2), # Round to 2 decimal places
}
return render(request, 'core/cancel-order.html', context)
def create_cancel(request, oid):
if request.method == "POST":
user = request.user
# Fetch POST data
reason = request.POST.get('reason')
description = request.POST.get('description')
try:
# Fetch the CartOrder instance
order_cancel = get_object_or_404(CartOrder, id=oid, user=user)
order_cancel.product_status = "cancelled"
order_cancel.save()
# Fetch related CartOrderItems instances
order_items = CartOrderItems.objects.filter(order=order_cancel)
for item in order_items:
item.product_status = "cancelled"
item.save()
# Log the reason and description (if you want to save this somewhere)
# Example: save to a cancellation model (optional)
# CancellationReason.objects.create(order=order_cancel, reason=reason, description=description)
messages.success(request, "Order successfully cancelled.")
except Exception as e:
messages.error(request, f"An error occurred: {e}")
return redirect("core:dashboard")
else:
messages.error(request, "Invalid request method.")
return redirect("core:dashboard")
Шаблон:
Вот форма в шаблоне cancel-order.html
:
Модели:
Вот модели CartOrder
и CartOrderItems
:
STATUS_CHOICE = (
("processing", "Processing"),
("shipped", "Shipped"),
("out_for_delivery", "Out for delivery"),
("delivered", "Delivered"),
("return_accepted", "Return Accepted"),
("pick_up", "Pick Up"),
("refund_completed", "Refund Completed"),
("cancelled", "Cancelled"),
)
class CartOrder(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
oid = ShortUUIDField(length=10, max_length=100, prefix="oid", alphabet="1234567890")
product_status = models.CharField(max_length=50, choices=STATUS_CHOICE, default="processing")
# Other fields...
class CartOrderItems(models.Model):
order = models.ForeignKey(CartOrder, on_delete=models.CASCADE, related_name="items")
product = models.ForeignKey(Product, on_delete=models.CASCADE)
qty = models.PositiveIntegerField(default=1)
product_status = models.CharField(max_length=50, choices=STATUS_CHOICE, default="processing")
# Other fields...
URLs: Вот шаблоны URL:
path("cancel_order/<int:oid>", cancel_order, name="cancel_order"),
path("create_cancel/<int:oid>", create_cancel, name="create_cancel"),
Наблюдаемое поведение:
- Форма
cancel-order.html
отображается корректно, а URL-адрес действия указывает на представлениеcreate_cancel
. - При отправке формы представление
create_cancel
не срабатывает. - Не отображаются сообщения об успехе или ошибке.
- Не вносятся изменения в
product_status
поля в базе данных.
Ожидаемое поведение:
При отправке формы должно срабатывать представление create_cancel
, которое должно обновлять поля product_status
для CartOrder
и связанные с ними CartOrderItems
. Соответственно должны отображаться сообщения Success
или error
.
Вопросы:
- Что может быть причиной того, что представление
create_cancel
не срабатывает при отправке формы? - Есть ли какие-либо общие проблемы с отправкой формы или разрешением URL в Django, которые я могу упустить из виду?
- Может ли это быть связано с тем, как передается параметр
oid
в URL или как обрабатывается запросPOST
?
Ок. Я нашел проблему. Я допустил ошибку в URL-адресах Мои взгляды:
def cancel_order(request, oid):
sub_category = SubCategory.objects.all()
categories = Category.objects.prefetch_related('subcategories').order_by('?')[:4]
wishlist = wishlist_model.objects.filter(user=request.user) if request.user.is_authenticated else None
nav_category = Category.objects.filter(special_category=True).prefetch_related('subcategories').order_by('?')[:4]
order = CartOrder.objects.get(user=request.user, id=oid)
products = CartOrderItems.objects.filter(order=order)
# Calculate discounts for each product
total_old_price = 0
total_price = 0
for item in products:
product = item.product # Assuming a ForeignKey from CartOrderItems to Product
qty = item.qty # Assuming a quantity field in CartOrderItems
total_old_price += (product.old_price or 0) * qty
total_price += (product.price or 0) * qty
# Calculate total discount percentage
if total_old_price > 0: # Prevent division by zero
discount_percentage = ((total_old_price - total_price) / total_old_price) * 100
else:
discount_percentage = 0
context = {
"order": order,
"products": products,
"sub_category": sub_category,
"categories": categories,
"wishlist": wishlist,
"nav_category": nav_category,
"discount_percentage": round(discount_percentage, 2), # Round to 2 decimal places
}
return render(request, 'core/cancel-order.html', context)
def create_cancel(request, oid):
if request.method == "POST":
user = request.user
# Fetch POST data
reason = request.POST.get('reason')
description = request.POST.get('description')
try:
# Fetch the CartOrder instance
order_cancel = get_object_or_404(CartOrder, id=oid, user=user)
order_cancel.product_status = "cancelled"
order_cancel.save()
# Fetch related CartOrderItems instances
order_items = CartOrderItems.objects.filter(order=order_cancel)
for item in order_items:
item.product_status = "cancelled"
item.save()
# Log the reason and description (if you want to save this somewhere)
# Example: save to a cancellation model (optional)
# CancellationReason.objects.create(order=order_cancel, reason=reason, description=description)
messages.success(request, "Order successfully cancelled.")
except Exception as e:
messages.error(request, f"An error occurred: {e}")
return redirect("core:dashboard")
else:
messages.error(request, "Invalid request method.")
return redirect("core:dashboard")
и в urls.py:
path("cancel_order/<int:oid>", cancel_order, name="cancel_order"),
path("create_cancel/<int:oid>", create_cancel, name="create_cancel"),
Ранее я запускал один и тот же вид cancel_order
вместо create_cancel