我无法在使用 django 的简单电子商务网站的结帐页面中看到购物车的商品

问题描述 投票:0回答:1

我无法在使用 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 的建议但什么也没发生,还清除了浏览器缓存并重新运行本地服务器,但都没用

django django-views django-templates
1个回答
0
投票

问题出在 url 模式中,而不是重定向到结帐 url,而是在登录 url 中设置为重定向。

© www.soinside.com 2019 - 2024. All rights reserved.