Django -将商品重新添加到购物篮的问题

wz8daaqr  于 2023-06-07  发布在  Go
关注(0)|答案(1)|浏览(188)

我在Djnago上创建了一个在线商店。该项目有一个篮子,你可以把货物,以及删除它们。货物放置和取出没有问题。但是,在产品被放置后,删除后-当重新添加此产品(已删除)到购物篮(用户始终相同)时-产品不会出现,问题是什么?下面是所有应用程序文件的代码:
models.py:

from django.db import models
from users.models import User

class ProductCategory(models.Model):
    name = models.CharField(max_length=128, unique=True)
    description = models.TextField(null=True, blank=True)

    def __str__(self):
        return self.name

class Product(models.Model):
    name = models.CharField(max_length=256)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveSmallIntegerField(default=0)
    image = models.ImageField(upload_to='products_images')
    category = models.ForeignKey(to=ProductCategory, on_delete=models.CASCADE)

    def __str__(self):
        return f'Product: {self.name} | Category: {self.category.name}'

class Basket(models.Model):
    user = models.ForeignKey(to=User, on_delete=models.CASCADE)
    product = models.ForeignKey(to=Product, on_delete=models.CASCADE)
    quantity = models.PositiveSmallIntegerField(default=0)
    created_timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f'Корзина для {self.user.username} | Продукт: {self.product.name}'

views.py:

from django.shortcuts import render, HttpResponseRedirect
from products.models import ProductCategory, Product, Basket
from users.models import User

def index(request):
    context = {
        'title': 'Store',
        'is_prom': True,
    }

    return render(request, 'products/index.html', context)

def products(request):
    context = {
        'title': 'Store - Каталог',
        'products': Product.objects.all(),
        'categories': ProductCategory.objects.all(),
    }

    return render(request, "products/products.html", context)

def basket_add(request, product_id):
    product = Product.objects.get(id=product_id)
    baskets = Basket.objects.filter(user=request.user, product=product)

    if not baskets.exists():
        Basket.objects.create(user=request.user, product=product, quantity=0)
    else:
        basket = baskets.first()
        basket.quantity += 1
        basket.save()

    return HttpResponseRedirect(request.META['HTTP_REFERER'])

def basket_remove(request, basket_id):
    basket = Basket.objects.get(id=basket_id)
    basket.delete()

    return HttpResponseRedirect(request.META['HTTP_REFERER'])

urls.py:

from django.urls import path
from products.views import products, basket_add, basket_remove

app_name = 'products'

urlpatterns = [
    path('', products, name='index'),
    path('baskets/add/<int:product_id>/', basket_add, name='basket_add'),
    path('baskets/remove/<int:basket_id>/', basket_remove, name='basket_remove'),
]

views.py - (其他应用程序,仅用于传递与篮子一起提交的上下文)

from django.shortcuts import render, HttpResponseRedirect
from django.contrib import auth, messages
from django.urls import reverse
from users.forms import UserLoginForm, UserRegistrationForm, UserProfileForm
from users.models import User
from products.models import Basket

def login(request):
    if request.method == 'POST':
        form = UserLoginForm(data=request.POST)

        if form.is_valid():
            username = request.POST['username']
            password = request.POST['password']
            user = auth.authenticate(username=username, password=password)

            if user:
                auth.login(request, user)
                return HttpResponseRedirect(reverse('index'))
    else:
        form = UserLoginForm()

    context = {'form': form}
    return render(request, 'users/login.html', context)

def registration(request):
    if request.method == 'POST':
        form = UserRegistrationForm(data=request.POST)

        if form.is_valid():
            form.save()
            messages.success(request, 'Поздравялем! Вы успешно зарегистрированы!')
            return HttpResponseRedirect(reverse('users:login'))
    else:
        form = UserRegistrationForm()

    context = {'form': form}
    return render(request, 'users/registration.html', context)

def profile(request):
    if request.method == 'POST':
        form = UserProfileForm(instance=request.user, data=request.POST, files=request.FILES)

        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('users:profile'))
        else:
            print(form.errors)
    else:
        form = UserProfileForm(instance=request.user)

    context = {
        'title': 'Store - Профиль',
        'form': form,
        'baskets': Basket.objects.filter(user=request.user),
    }
    return render(request, 'users/profile.html', context)

def logout(request):
    auth.logout(request)

    return HttpResponseRedirect(reverse('index'))

products.html:

{% extends "products/base.html" %}
{% load static %}

{% block css %}
<link href="{% static 'vendor/css/products.css' %}" rel="stylesheet">
{% endblock %}

{% block content %}
<div class="container">

    <div class="row">

        <div class="col-lg-3">

            <h1 class="my-4">Store</h1>
            <div class="list-group">
                {% for category in categories %}
                    <a href="#" class="list-group-item">{{ category.name }}</a>
                {% endfor %}
            </div>

        </div>
        <!-- /.col-lg-3 -->

        <div class="col-lg-9">

            <div id="carouselExampleIndicators" class="carousel slide my-4" data-ride="carousel">
                <ol class="carousel-indicators">
                    <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
                    <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
                    <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
                </ol>
                <div class="carousel-inner" role="listbox">
                    <div class="carousel-item active">
                        <img class="d-block img-fluid" src="{% static 'vendor/img/slides/slide-1.jpg' %}" alt="First slide">
                    </div>
                    <div class="carousel-item">
                        <img class="d-block img-fluid" src="{% static 'vendor/img/slides/slide-2.jpg' %}" alt="Second slide">
                    </div>
                    <div class="carousel-item">
                        <img class="d-block img-fluid" src="{% static 'vendor/img/slides/slide-3.jpg' %}" alt="Third slide">
                    </div>
                </div>
                <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
                    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                    <span class="sr-only">Previous</span>
                </a>
                <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
                    <span class="carousel-control-next-icon" aria-hidden="true"></span>
                    <span class="sr-only">Next</span>
                </a>
            </div>

            <div class="row">

                {% for product in products %}
                <div class="col-lg-4 col-md-6 mb-4">
                    <div class="card h-100">
                        <a href="#">
                            <img class="card-img-top" src="{{ product.image.url }}" alt="">
                        </a>
                        <div class="card-body">
                            <h4 class="card-title">
                                <a href="#">{{ product.name }}</a>
                            </h4>
                            <h5>{{ product.price }} руб.</h5>
                            <p class="card-text">{{ product.description }}</p>
                        </div>
                        <div class="card-footer text-center">
                            <a class="btn btn-outline-success" href="{% url 'products:basket_add' product.id %}">Отправить в корзину</a>
                        </div>
                    </div>
                </div>
                {% endfor %}

            </div>

            <nav aria-label="Page navigation example">
                <ul class="pagination justify-content-center">
                    <li class="page-item disabled">
                        <a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a>
                    </li>
                    <li class="page-item"><a class="page-link" href="#">1</a></li>
                    <li class="page-item"><a class="page-link" href="#">2</a></li>
                    <li class="page-item"><a class="page-link" href="#">3</a></li>
                    <li class="page-item">
                        <a class="page-link" href="#">Next</a>
                    </li>
                </ul>
            </nav>

        </div>

    </div>

</div>
<!-- /.container -->
{% endblock %}

{% block footer %}
<footer class="py-5 bg-dark">
    <div class="container">
        <p class="m-0 text-center text-white">Copyright &copy; Store 2022</p>
    </div>
    <!-- /.container -->
</footer>
{% endblock %}

profile.html:

{% extends 'products/base.html' %}
    {% load static %}

    {% block css %}
        <link href="{% static 'vendor/css/profile.css' %}" rel="stylesheet">
    {% endblock %}

    {% block content%}
    <div class="container">
        <div class="row">
            <div class="col-lg-7">
                <h4 class="mt-3 mb-3">Профиль</h4>
                <div class="col-lg-12 text-center">
                    <img width="100" height="100"
                        src="{% if user.image %} {{ user.image.url }} {% else %} {% static 'vendor/img/users/default_avatar.jpg' %} {% endif %}">
                </div>
                <form action="{% url 'users:profile' %}" method="post" enctype="multipart/form-data">
                    {% csrf_token %}
                    <div class="form-row">
                        <div class="col-lg-6">
                            <div class="form-group">
                                <label class="small mb-1" for="{{ form.first_name.id_for_lable }}">Имя</label>
                                {{ form.first_name }}
                            </div>
                        </div>
                        <div class="col-lg-6">
                            <div class="form-group">
                                <label class="small mb-1" for="{{ form.last_name.id_for_lable }}">Фамилия</label>
                                {{ form.last_name }}
                            </div>
                        </div>
                    </div>
                    <div class="form-row mb-2">
                        <div class="col-lg-12">
                            <div class="custom-file">
                                {{ form.image }}
                                <label class="custom-file-label" for="{{ form.image.id_for_lable }}">Выберите изображение</label>
                            </div>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-lg-6">
                            <label class="small mb-1" for="{{ form.username.id_for_lable }}">Имя пользователя</label>
                            {{ form.username }}
                        </div>
                        <div class="col-lg-6">
                            <label class="small mb-1" for="{{ form.email.id_for_lable }}">Адрес электронной
                                почты</label>
                                {{ form.email }}
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="col-lg-12" style="margin-top: 33px;">
                            <input class="btn btn-info btn-block" type="submit" value="Сохранить">
                        </div>
                    </div>
                </form>
            </div>
            <div class="col-lg-5">
                {% include 'products/baskets.html' %}
            </div>
        </div>
    </div>
    {% endblock %}

baskets.html

{% if baskets %}
    <h4 class="mt-3 mb-3 d-flex justify-content-between align-items-center mb-3">
        Корзина <span class="badge badge-secondary badge-pill">3</span>
    </h4>
    {% for basket in baskets %}
        <div class="card mb-3">
            <div class="card-body">
                <h5 class="card-title">{{ basket.product.name }}</h5>
                <p class="card-text">{{ basket.product.description }}</p>
            </div>
            <ul class="list-group list-group-flush">
                <li class="list-group-item bg-light">
                    <div class="row text-center">
                        <div class="col-lg-4">
                            <input name="basketID" type="number" class="form-control"
                                value="{{ basket.quantity }}" min="0">
                        </div>
                        <div class="col-lg-4">2 390 руб.</div>
                        <div class="col-lg-4">
                            <a href="{% url 'products:basket_remove' basket.id %}">
                                <i class="fas fa-trash"></i>
                            </a>
                        </div>
                    </div>
                </li>
            </ul>
        </div>
    {% endfor %}
<div class="card mb-3">
    <div class="card-footer">
        <p class="float-left">Итого</p>
        <h4 class="float-right">2 390 руб.</h4>
    </div>
</div>
<a class="btn btn-success btn-lg float-right" href="../orders/order-create.html">
    Оформить заказ
</a>
{% else %}
<h4 class="mt-3 mb-3 text-center">
    Корзина пуста
{% endif %}

我想不出有什么问题。我的代码就像作者的代码。

mo49yndu

mo49yndu1#

仍然很难理解这个主题-我建议你在basket_add中添加一些“打印”,并在控制台中看到真正发生的事情:

def basket_add(request, product_id):
    product = Product.objects.get(id=product_id)
    baskets = Basket.objects.filter(user=request.user, product=product)

    print("******** in basket_add ******")
    print("******** product: " ,product)
    print("******** baskets: " ,baskets)

    if not baskets.exists():
        print("******** basket does not exist -> create it")
        Basket.objects.create(user=request.user, product=product, quantity=0)
    else:
        print("******** basket exists ->  increase quantity")
        basket = baskets.first()
        basket.quantity += 1
        basket.save()

注意:这不是复杂的调试(最好使用日志记录),但这里是最简单的方法。
还有一些评论的逻辑:

  • 每种产品一个篮子是不寻常的
  • 在产品添加时,如果购物篮尚不存在,则创建购物篮,但数量=0
  • 产品移除不会减少数量,而是删除整个购物篮。
  • baskets.html中有一个名为basketID的输入字段,实际上包含了数量:
<input name="basketID" type="number" class="form-control"
                                value="{{ basket.quantity }}" min="0">

相关问题