我无法在使用 django 的简单电子商务网站的结帐页面中看到购物车中的商品,添加的产品显示在购物车页面上,但不会显示在结帐页面中,而且当我想在结帐页面下订单时,也不会添加任何内容到django管理面板的订单页面,管理面板的购物车项目显示产品已添加,但是当我下订单时,管理面板的订单部分没有订单,在下面您可以看到项目代码:
models.py:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
# Create your models here.
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.FloatField()
stock = models.IntegerField()
short_description = models.TextField()
long_description = models.TextField()
image = models.ImageField()
production_date = models.DateField()
product_id = models.IntegerField()
def __str__(self):
return self.name
#user
class UserManager(BaseUserManager):
def create_user(self, phone_number, password=None):
if not phone_number:
raise ValueError("Users must have a phone number")
user = self.model(phone_number=phone_number)
user.set_password(password) # Set password if needed
user.save(using=self._db)
return user
def create_superuser(self, phone_number, password=None):
user = self.create_user(phone_number, password)
user.is_admin = True
user.is_staff = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
phone_number = models.CharField(max_length=15, unique=True)
USERNAME_FIELD = 'phone_number'
objects = UserManager()
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_lable):
return True
def __str__(self):
return self.phone_number
class CartItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=0)
user = models.ForeignKey(User, on_delete=models.CASCADE)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.quantity} x {self.product.name}'
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
address = models.CharField(max_length=250)
payment_choice = models.CharField(max_length=20)
order_price = models.DecimalField(max_digits=10, decimal_places=2)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Order {self.id} by {self.user.phone_number}"
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return f"{self.quantity} of {self.product.name} in Order {self.order.id}"
views.py
import logging
from django.contrib.auth.models import AnonymousUser
from django.db import transaction
import random
import django
from home.forms import *
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from home.models import *
django.setup()
# Create your views here.
def product_list(request):
products = Product.objects.all() # Fetch all products
return render(request, 'home/product_list.html', {'products': products})
# Dummy function to simulate sending messages
def send_otp(phone_number, otp):
print(f"Sending OTP {otp} to {phone_number}")
def generate_otp():
return str(random.randint(1000, 9999))
otp_store = {} # In a real setting, save to a database or cache
def signup_view(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
phone_number = form.cleaned_data['phone_number']
user, created = User.objects.get_or_create(phone_number=phone_number)
if created:
# Generate OTP
otp = generate_otp()
otp_store[phone_number] = otp
send_otp(phone_number, otp)
return redirect('verify_otp', phone_number=phone_number)
else:
messages.error(request, "This phone number is already registered.")
else:
form = SignupForm()
return render(request, 'home/signup.html', {'form': form})
def verify_otp_view(request, phone_number):
if request.method == 'POST':
form = OTPVerificationForm(request.POST)
if form.is_valid():
otp = form.cleaned_data['otp']
if otp_store.get(phone_number) == otp:
# OTP is correct, user can be logged in or registered fully
messages.success(request, "OTP verified successfully.")
del otp_store[phone_number] # Clear OTP
return redirect('product_list') # Redirect to login or homepage
else:
messages.error(request, "Invalid OTP.")
else:
form = OTPVerificationForm()
return render(request, 'home/verify_otp.html', {'form': form, 'phone_number': phone_number})
def view_cart(request):
if isinstance(request.user, AnonymousUser):
# Handle unauthenticated users
cart = request.session.get('cart', {})
cart_items = []
total_price = 0
for product_id, quantity in cart.items():
try:
product = Product.objects.get(id=product_id)
item_total = product.price * quantity
cart_items.append({
'id': product_id, # This is crucial for the remove_from_cart URL
'product': product,
'quantity': quantity,
'total': item_total
})
total_price += item_total
except Product.DoesNotExist:
# Handle case where product no longer exists
pass
else:
# Handle authenticated users
cart_items = CartItem.objects.filter(user=request.user)
total_price = sum(item.product.price * item.quantity for item in cart_items)
return render(request, 'home/cart.html', {'cart_items': cart_items, 'total_price': total_price})
logger = logging.getLogger(__name__)
@login_required
def checkout(request):
user = request.user
logger.info(f"Checkout initiated for user: {user.username}")
# Fetch cart items
cart_items = CartItem.objects.filter(user=user)
logger.info(f"Number of cart items retrieved: {cart_items.count()}")
# Log each cart item
for item in cart_items:
logger.info(f"Cart item: {item.product.name}, Quantity: {item.quantity}, Price: {item.product.price}")
# Calculate total price
total_price = sum(item.product.price * item.quantity for item in cart_items)
logger.info(f"Total price calculated: {total_price}")
if request.method == 'POST':
logger.info("POST request received for checkout")
address = request.POST.get('address')
payment_choice = request.POST.get('payment_choice')
logger.info(f"Address: {address}, Payment Choice: {payment_choice}")
if not address or not payment_choice:
logger.warning("Missing address or payment choice")
messages.error(request, "Please provide both address and payment choice.")
return render(request, 'home/checkout.html', {'cart_items': cart_items, 'total_price': total_price})
if cart_items.exists():
try:
with transaction.atomic():
logger.info("Creating order")
order = Order.objects.create(
user=user,
address=address,
payment_choice=payment_choice,
order_price=total_price
)
logger.info(f"Order created with ID: {order.id}")
for cart_item in cart_items:
logger.info(f"Creating OrderItem for product: {cart_item.product.name}")
OrderItem.objects.create(
order=order,
product=cart_item.product,
quantity=cart_item.quantity,
price=cart_item.product.price
)
logger.info("Deleting cart items")
cart_items.delete()
messages.success(request, "Order placed successfully!")
logger.info(f"Order {order.id} placed successfully")
return redirect('order_detail', order_id=order.id)
except Exception as e:
logger.error(f"Error creating order: {str(e)}", exc_info=True)
messages.error(request, f"An error occurred while processing your order: {str(e)}")
return redirect('view_cart')
else:
logger.warning("Attempted to checkout with empty cart")
messages.error(request, "Your cart is empty.")
return redirect('view_cart')
logger.info("Rendering checkout template")
return render(request, 'home/checkout.html', {'cart_items': cart_items, 'total_price': total_price})
def add_to_cart(request, product_id):
product = get_object_or_404(Product, id=product_id)
logger.info(f"Adding product to cart: {product.name}")
if request.user.is_authenticated:
cart_item, created = CartItem.objects.get_or_create(product=product, user=request.user)
cart_item.quantity += 1
cart_item.save()
logger.info(f"Added to CartItem for user {request.user.phone_number}: {cart_item}")
else:
cart = request.session.get('cart', {})
cart[str(product_id)] = cart.get(str(product_id), 0) + 1
request.session['cart'] = cart
logger.info(f"Added to session cart for anonymous user. Cart contents: {cart}")
messages.success(request, f"Added {product.name} to your cart.")
return redirect('view_cart')
def remove_from_cart(request, item_id):
cart_item = CartItem.objects.get(id=item_id)
cart_item.delete()
return redirect('view_cart')
def checkout_redirect(request):
if request.user.is_authenticated:
return redirect('checkout') # Replace with the actual checkout URL name
else:
return redirect('signup') # Replace with the actual login URL name
@login_required
def order_detail(request, order_id):
order = get_object_or_404(Order, id=order_id, user=request.user)
return render(request, 'home/order_detail.html', {'order': order})
结账.html
<html lang="en">
<body>
<form method="POST">
{% csrf_token %}
<h2>Checkout</h2>
<label for="address">Shipping Address:</label><br>
<textarea name="address" required></textarea><br>
<label for="receiver">receiver:</label><br>
<textarea name="receiver" required></textarea><br>
<label for="payment_choice">Payment Method:</label><br>
<select name="payment_choice" required>
<option value="online">Online</option>
<option value="pay_on_delivery">Pay on Delivery</option>
</select><br>
<button type="submit">Place Order</button>
</form>
<h3>Your Cart Items:</h3>
<ul>
{% for item in cart_items %}
<li>{{ item.product.name }} - {{ item.quantity }} @ {{ item.product.price }} each</li>
{% endfor %}
</ul>
{% for item in cart_items %}
<div class="product-item">
<p>{{ item.product.name }} ({{ item.quantity }})</p>
<p>Price: ${{ item.product.price }}</p>
<a href="{% url 'remove_from_cart' item.id %}">Remove</a>
</div>
{% empty %}
<p>Your cart is empty.</p>
{% endfor %}
</body>
</html>
你
# urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path
from home.views import *
# urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
from django.contrib.auth import views as auth_views
from home.views import *
urlpatterns = [
path('', product_list, name='product_list'),
path('signup/', signup_view, name='signup'),
path('verify-otp/<str:phone_number>/', verify_otp_view, name='verify_otp'),
path('cart/', view_cart, name='view_cart'),
path('add/<int:product_id>/', add_to_cart, name='add_to_cart'),
path('remove/<int:item_id>/', remove_from_cart, name='remove_from_cart'),
path('checkout/', checkout, name='checkout'),
path('order/<int:order_id>/', order_detail, name='order_detail'),
path('checkout/redirect/', checkout_redirect, name='checkout_redirect'),
path('login/', auth_views.LoginView.as_view(template_name='home/checkout.html'), name='checkout'),
path('accounts/', include('django.contrib.auth.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
ls.py 如有必要
我已经从结帐页面跟踪了 orderitem 循环代码以进行查看和建模,但对我来说看起来不错,我使用了 AI 的建议但什么也没发生,还清除了浏览器缓存并重新运行本地服务器,但都没用
问题出在 url 模式中,而不是重定向到结帐 url,而是在登录 url 中设置为重定向。