python - Django:取消订单时无法调整库存
问题描述
因此,在我的网站中,当用户取消订单时,我希望恢复用户购买的产品库存,但每当我测试它时,库存保持不变(但当用户购买东西时成功减少)。我尝试使用的功能adjust_stock
在order/views.py中,如下所示:
from django.shortcuts import render, get_object_or_404, redirect
from .models import OrderItem, Order
from cart.models import Cart, CartItem
from cart.views import _cart_id
from shop.models import Product
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.decorators import login_required
from datetime import datetime, timezone
from django.contrib import messages
from django.core.paginator import Paginator, EmptyPage, InvalidPage
import stripe
@login_required()
def order_create(request, total=0, cart_items = None):
if request.method == 'POST':
cart = Cart.objects.get(cart_id=_cart_id(request))
cart_items = CartItem.objects.filter(cart=cart)
for item in cart_items:
total += (item.quantity * item.product.price)
print('Total', total)
charge = stripe.Charge.create(
amount=str(int(total*100)),
currency='EUR',
description = 'Credit card charge',
source=request.POST['stripeToken']
)
if request.user.is_authenticated:
email = str(request.user.email)
order_details = Order.objects.create(emailAddress = email)
order_details.save()
try:
cart = Cart.objects.get(cart_id=_cart_id(request))
cart_items = CartItem.objects.filter(cart=cart)
for order_item in cart_items:
oi = OrderItem.objects.create(
product = order_item.product.name,
quantity = order_item.quantity,
price = order_item.product.price,
order = order_details)
total += (order_item.quantity * order_item.product.price)
oi.save()
#Reduce stock when order is placed or saved
products = Product.objects.get(id=order_item.product_id)
if products.stock > 0:
products.stock = int(order_item.product.stock - order_item.quantity)
products.save()
order_item.delete()
except ObjectDoesNotExist:
pass
return render(request, 'order.html', dict(cart_items = cart_items, total=total))
def adjust_stock(id, quantity):
products = Product.objects.filter(id=id)
products.stock = int(product.stock + quantity)
products.save()
@login_required()
def order_history(request):
if request.user.is_authenticated:
email = str(request.user.email)
order_details = Order.objects.filter(emailAddress=email)
paginator = Paginator(order_details, 3)
try:
page = int(request.GET.get('page', '1'))
except:
page = 1
try:
orders = paginator.page(page)
except (EmptyPage, InvalidPage):
orders = paginator.page(paginator.num_pages)
return render(request, 'orders_list.html', {'orders':orders})
def cancel_order(request, order_id):
order = get_object_or_404(Order, id=order_id)
order_date = order.created
current_date = datetime.now(timezone.utc)
date_diff = current_date - order_date
minutes_diff = date_diff.total_seconds() / 60.0
order_items = OrderItem.objects.filter(id=order_id)
if minutes_diff <= 30:
for product in order_items:
product.adjust_stock(order_items.product.id, order_items.quantity)
order.delete()
messages.add_message(request, messages.INFO,
'Your order is cancelled.')
else:
messages.add_message(request, messages.INFO,
'Sorry, it is too late to cancel this order.')
return redirect('order_history')
如您所见,我在cancel_order
函数中调用它,但它似乎不起作用。任何帮助都将不胜感激!以下是相关代码的其余部分:
订单/models.py
from django.db import models
from shop.models import Product
class Order(models.Model):
created = models.DateTimeField(auto_now_add=True)
emailAddress = models.EmailField(max_length=250, blank=True)
class Meta:
db_table = 'Order'
ordering = ('-created', )
def __str__(self):
return 'Order {}'.format(self.id)
def get_total_cost(self):
return sum(item.get_cost() for item in self.items.all())
def get_items(self):
return OrderItem.objects.filter(order=self)
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.CharField(max_length=250)
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
def __str__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price * self.quantity
购物车/models.py
from django.db import models
from shop.models import Product
class Cart(models.Model):
cart_id = models.CharField(max_length=250, blank = True)
date_added = models.DateField(auto_now_add=True)
class Meta:
db_table = 'Cart'
ordering = ['date_added']
def __str__(self):
return self.cart_id
class CartItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
quantity = models.IntegerField()
class Meta:
db_table = 'CartItem'
def sub_total(self):
return self.product.price * self.quantity
def __str__(self):
return self.product
购物车/views.py
from django.shortcuts import render, redirect, get_object_or_404
from shop.models import Product
from .models import Cart, CartItem
from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
import stripe
# Create your views here.
def _cart_id(request):
cart = request.session.session_key
if not cart:
cart = request.session.create()
return cart
def add_cart(request, product_id):
product = Product.objects.get(id=product_id)
try:
cart = Cart.objects.get(cart_id=_cart_id(request))
except Cart.DoesNotExist:
cart = Cart.objects.create(
cart_id = _cart_id(request)
)
cart.save()
try:
cart_item = CartItem.objects.get(product=product, cart=cart)
if cart_item.quantity < cart_item.product.stock:
cart_item.quantity += 1
cart_item.save()
else:
messages.add_message(request, messages.INFO,
'Sorry, no more of this item available')
except CartItem.DoesNotExist:
cart_item = CartItem.objects.create(
product = product,
quantity = 1,
cart = cart
)
cart_item.save()
return redirect('cart_detail')
def cart_detail(request, total=0, counter=0, cart_items = None):
try:
cart = Cart.objects.get(cart_id=_cart_id(request))
cart_items = CartItem.objects.filter(cart=cart)
for cart_item in cart_items:
total += (cart_item.product.price * cart_item.quantity)
counter += cart_item.quantity
except ObjectDoesNotExist:
pass
stripe.api_key = settings.STRIPE_SECRET_KEY
stripe_total = int(total*100)
description = 'MyTea - Order'
data_key = settings.STRIPE_PUBLISHABLE_KEY
return render(request, 'cart.html', dict(cart_items = cart_items, total = total,
counter = counter, data_key = data_key, stripe_total = stripe_total, description = description))
def cart_remove(request, product_id):
cart = Cart.objects.get(cart_id=_cart_id(request))
product = get_object_or_404(Product, id=product_id)
cart_item = CartItem.objects.get(product=product, cart=cart)
if cart_item.quantity > 1:
cart_item.quantity -= 1
cart_item.save()
else:
cart_item.delete()
return redirect('cart_detail')
def full_remove(request):
cart = Cart.objects.get(cart_id=_cart_id(request))
cart_items = CartItem.objects.filter(cart=cart)
for cart_item in cart_items:
cart_item.delete()
return redirect('cart_detail')
谢谢!
解决方案
products = Product.objects.filter(id=id) 应该是 product = Product.objects.get(id=id)
在查询集上调用 stock attr 应该在您的请求中引发错误?
推荐阅读
- robotframework - 带有机器人框架的测试模板不能使用变量
- python-3.x - 无服务器框架:从文件和堆栈输出设置环境变量
- ios - 在 Swift 中以编程方式修改视图高度
- r - 用于获取对变量的引用的 R 函数
- android - Android Lollipop:不能在 GridLayout 中包含外部布局
- node.js - Twilio Whatsapp:发送多媒体消息
- c++ - 前向打包在模板类中不起作用
- java-7 - 在 ubuntu 中更改 jdeveloper 11g(11.2) 的 JDK 版本
- java - 使用 Java 8 重构多态性
- javascript - 深度嵌套对象中未定义变量的默认值