Python DJANGO电子商务网站需要帮助。不同的订单具有相同的订单项
所以我跟随YouTube上的教程,用DJANGO制作一个电子商务网站,但问题是,现在我已经完成了教程,我意识到有些地方出了问题。因此,每当我下一个新订单时,该订单中都有订单项,因为订单模型有一个带有订单项的manytomanyfield。所以我下了一个订单并保存了它。但是如果我下了第二个订单,然后保存它,第一个订单的订单项将与第二个订单项相等,这是不应该发生的。我已经做了4个小时了,我不知道该怎么办,所以我非常感谢你的帮助。两个订单都有不同的ref_代码,因此至少可以正常工作。随附两份订单的管理员视图截图。Python DJANGO电子商务网站需要帮助。不同的订单具有相同的订单项,python,django,Python,Django,所以我跟随YouTube上的教程,用DJANGO制作一个电子商务网站,但问题是,现在我已经完成了教程,我意识到有些地方出了问题。因此,每当我下一个新订单时,该订单中都有订单项,因为订单模型有一个带有订单项的manytomanyfield。所以我下了一个订单并保存了它。但是如果我下了第二个订单,然后保存它,第一个订单的订单项将与第二个订单项相等,这是不应该发生的。我已经做了4个小时了,我不知道该怎么办,所以我非常感谢你的帮助。两个订单都有不同的ref_代码,因此至少可以正常工作。随附两份订单的管理
Youtube教程: Models.py
from django.db import models
from django.conf import settings
from django.shortcuts import reverse
# Create your models here.
CATEGORY_CHOICES = (
('S', 'Shirt'),
('SW', 'Sport Wear'),
('OW', 'Outwear'),
)
LABEL_CHOICES = (
('P', 'primary'),
('S', 'secondary'),
('D', 'danger'),
)
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.FloatField(default=0)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
description = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("core:product", kwargs={
'slug': self.slug
})
def get_add_to_cart_url(self):
return reverse("core:add-to-cart", kwargs={
'slug': self.slug
})
def get_remove_from_cart_url(self):
return reverse("core:remove-from-cart", kwargs={
'slug': self.slug
})
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ordered = models.BooleanField(default=False)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def get_total_item_price(self):
return self.quantity * self.item.price
def get_total_discounted_item_price(self):
return self.quantity * self.item.discount_price
def get_amount_saved(self):
return self.get_total_item_price() - self.get_total_discounted_item_price()
def get_final_price(self):
if self.item.discount_price:
return self.get_total_discounted_item_price()
return self.get_total_item_price()
def __str__(self):
return f"{self.quantity} of {self.item.title}"
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
ref_code = models.CharField(max_length=20,default="0")
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
billing_address = models.ForeignKey('BillingAddress', on_delete=models.SET_NULL, blank=True, null=True)
being_delivered = models.BooleanField(default=False)
received = models.BooleanField(default=False)
refund_requested = models.BooleanField(default=False)
refund_granted = models.BooleanField(default=False)
def __str__(self):
return self.user.username
def get_total(self):
total = 0
for order_item in self.items.all():
total += order_item.get_final_price()
return total
Views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.views.generic import ListView, DetailView, View
from django.contrib import messages
from .models import *
from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from .forms import *
import random
import string
# Create your views here.
def create_ref_code():
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=20))
class CheckoutView(View):
def get(self, *args, **kwargs):
form = CheckoutForm()
order = Order.objects.get(user=self.request.user, ordered=False)
stuff_for_frontend = {
'form': form,
'order': order,
}
return render(self.request, 'checkout.html', stuff_for_frontend)
def post(self, *args, **kwargs):
form = CheckoutForm(self.request.POST or None)
try:
order = Order.objects.get(user=self.request.user, ordered=False)
if form.is_valid():
if not ('0' <= form.cleaned_data.get('mobile_number') <= '99999999999'):
messages.warning(self.request, "Mobile Number is invalid")
messages.warning(self.request, "Failed Checkout")
return redirect('core:checkout')
street_address = form.cleaned_data.get('street_address')
apartment_address = form.cleaned_data.get('apartment_address')
mobile_number = form.cleaned_data.get('mobile_number')
city = form.cleaned_data.get('city')
zip = form.cleaned_data.get('zip')
# same_shipping_address = form.cleaned_data.get('same_shipping_address')
# save_info = form.cleaned_data.get('save_info')
payment_option = form.cleaned_data.get('payment_option')
billing_address = BillingAddress(
user=self.request.user,
street_address=street_address,
apartment_address=apartment_address,
mobile_number=mobile_number,
city=city,
zip=zip
)
billing_address.save()
order.billing_address = billing_address
order.ordered = True
order.ref_code = create_ref_code()
order.save()
messages.success(self.request, "Your order was successful")
return redirect('/')
messages.warning(self.request, "Failed Checkout")
return redirect('core:checkout')
except ObjectDoesNotExist:
messages.error(self.request, "You do not have an active order")
return redirect("core:order-summary")
class HomeView(ListView):
model = Item
paginate_by = 10
template_name = "home.html"
class ItemDetailView(DetailView):
model = Item
template_name = 'product.html'
class OrderSummary(LoginRequiredMixin, View):
def get(self, *args, **kwargs):
try:
order = Order.objects.get(user=self.request.user, ordered=False)
stuff_for_frontend = {
'object': order
}
return render(self.request, 'order_summary.html', stuff_for_frontend)
except ObjectDoesNotExist:
messages.error(self.request, "You do not have an active order")
return redirect("/")
@login_required
def add_to_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
order_item, created = OrderItem.objects.get_or_create(item=item, user=request.user, ordered=False)
order_qs = Order.objects.filter(user=request.user, ordered=False)
if order_qs.exists():
order = order_qs[0]
print(order_qs)
if order.items.filter(item__slug=item.slug).exists():
order_item.quantity += 1
order_item.save()
messages.info(request, "This item's quantity was updated")
return redirect("core:order-summary")
else:
order.items.add(order_item)
messages.info(request, "This item was added to your cart")
return redirect("core:order-summary")
else:
order = Order.objects.create(user=request.user, ordered_date=timezone.now())
order.items.add(order_item)
messages.info(request, "This item was added to your cart")
return redirect("core:order-summary")
@login_required
def remove_from_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
order_qs = Order.objects.filter(user=request.user, ordered=False)
if order_qs.exists():
order = order_qs[0]
if order.items.filter(item__slug=item.slug).exists():
order_item = OrderItem.objects.filter(item=item, user=request.user, ordered=False)[0]
order.items.remove(order_item)
messages.info(request, "This item was removed from your cart")
return redirect("core:order-summary")
else:
messages.info(request, "This item was not in your cart")
return redirect("core:product", slug=slug)
else:
messages.info(request, "You do not have an active order")
return redirect("core:product", slug=slug)
@login_required
def remove_single_item_from_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
order_qs = Order.objects.filter(user=request.user, ordered=False)
if order_qs.exists():
order = order_qs[0]
if order.items.filter(item__slug=item.slug).exists():
order_item = OrderItem.objects.filter(item=item, user=request.user, ordered=False)[0]
if order_item.quantity > 1:
order_item.quantity -= 1
messages.info(request, "This item quantity was updated")
else:
order.items.remove(order_item)
messages.info(request, "This item was removed from your cart")
order_item.save()
return redirect("core:order-summary")
else:
messages.info(request, "This item was not in your cart")
return redirect("core:product", slug=slug)
else:
messages.info(request, "You do not have an active order")
return redirect("core:product", slug=slug)
从django.shortcuts导入渲染,获取对象或重定向
从django.views.generic导入ListView、DetailView、View
从django.contrib导入消息
从。模型导入*
从django.utils导入时区
从django.core.exceptions导入ObjectDoesNotExist
从django.contrib.auth.decorators导入所需的登录名
从django.contrib.auth.mixins导入登录名RequiredMixin
从。表格导入*
随机输入
导入字符串
#在这里创建您的视图。
def create_ref_code():
返回“”。联接(随机.choices(string.ascii_小写+string.digits,k=20))
类签出视图(视图):
def get(自身、*args、**kwargs):
表单=CheckoutForm()
order=order.objects.get(user=self.request.user,ordered=False)
用于前端的内容={
“形式”:形式,
“秩序”:秩序,
}
返回渲染(self.request,'checkout.html',stuff_for_frontend)
def post(自我,*args,**kwargs):
表单=检查表单(self.request.POST或无)
尝试:
order=order.objects.get(user=self.request.user,ordered=False)
如果form.is_有效():
如果不是('0'
{%endblock内容%}
OrderItems应具有Order的ForeignKey;Orders不应具有OrderItems的ManyToManyField,因为一个OrderItem不应属于多个订单
此外,OrderItems应该缓存所订购商品的价格-否则,如果您以后要更改商品的价格,则无法运行随时间变化的商品价格报告。谢谢。我如何缓存价格。我是否只创建一个字段“price=self.item.price”是的。我推荐单价
,数量
,折扣
,总价
,其中总价=(单价*数量)-折扣
,但语义由您决定。
{% extends 'base.html' %}
{%block content%}
<!--Main layout-->
<main>
<div class="container">
<div class="table-responsive text-nowrap">
<h2>Order Summary</h2>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Item title</th>
<th scope="col">Price</th>
<th scope="col">Discounted Price</th>
<th scope="col">Quantity</th>
<th scope="col">Total Item Price</th>
</tr>
</thead>
<tbody>
<tr>
{%for order_item in object.items.all%}
<th scope="row">{{forloop.counter}}</th>
<td>{{order_item.item.title}}</td>
<td>{{order_item.item.price}}</td>
<td>{{order_item.item.discount_price}}</td>
<td><a href="{% url 'core:remove-single-item-from-cart' order_item.item.slug %}"><i class="fas fa-minus mr-2"></i></a>{{order_item.quantity}}<a href="{% url 'core:add-to-cart' order_item.item.slug %}"><i class="fas fa-plus ml-2"></i></a></td>
<td>
{%if order_item.item.discount_price%}
${{order_item.get_total_discounted_item_price}}
<span class="badge badge-success">Saving ${{order_item.get_amount_saved}}</span>
{%else%}
${{order_item.get_total_item_price}}
{%endif%}
<a style="color:red;" href="{% url 'core:remove-from-cart' order_item.item.slug %}"><i class="fas fa-trash float-right"></i></a>
</td>
</tr>
{%empty%}
<tr>
<td colspan='5'>Your cart is empty</td>
</tr>
<tr>
<td colspan="6">
<a class="btn btn-dark float-right " href="/">Continue Shopping</a>
</td>
</tr>
{%endfor%}
{%if object.get_total %}
<tr>
<td colspan="5"><b>Order Total</b></td>
<td colspan="5"><b>${{object.get_total}}</b></td>
</tr>
<tr>
<td colspan="6">
<a class="btn btn-primary float-right ml-2" href="/checkout">Proceed to checkout</a>
<a class="btn btn-dark float-right " href="/">Continue Shopping</a>
</td>
</tr>
{%endif%}
</tbody>
</table>
</div>
</div>
</main>
<!--Main layout-->
{%endblock content%}