feat: implement shopping cart feature with user authentication support
All checks were successful
Build and Push Docker Image / build (push) Successful in 42s

- Added `Cart` and `CartItem` models with migrations for managing user-specific carts and items
- Developed services for cart-related operations: adding, removing, and updating cart items
- Built specialized templates (`cart.html`) and styled them with new CSS assets (`cart.css`)
- Enabled real-time UI updates via AJAX in shopping cart interactions (`cart.js`)
- Modified header to dynamically display cart link with user authentication awareness
- Added Leaflet-based interactive map to the contacts page and integrated CSS/JS dependencies
- Expanded tests for cart functionality, item detail page cart integration, and contacts page maps
This commit is contained in:
2026-05-15 23:18:16 +02:00
parent d2126e0fba
commit 52cbc1c2b3
22 changed files with 1317 additions and 18 deletions

View File

@@ -4,6 +4,7 @@ from django.core.exceptions import ValidationError
from favorites.models import Favorite
from items.models import Category, Item, ItemImage, Subcategory
from orders.models import Cart, CartItem
@override_settings(MEDIA_URL="/media/")
@@ -215,6 +216,44 @@ class CatalogViewTests(TestCase):
self.assertEqual(response.status_code, 404)
def test_detail_page_shows_cart_link_for_item_already_in_cart(self):
user = get_user_model().objects.create_user(
username="cart-user",
email="cart-user@example.com",
password="StrongPassword123",
is_active=True,
)
cart = Cart.objects.create(user=user)
CartItem.objects.create(cart=cart, item=self.sink, quantity=1)
self.client.force_login(user)
response = self.client.get("/catalog/plumbing/kitchen-sink/")
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'href="/orders/cart/"', html=False)
self.assertContains(response, "Перейти в корзину")
def test_detail_page_guest_cart_cta_redirects_to_login(self):
response = self.client.get("/catalog/plumbing/kitchen-sink/")
self.assertEqual(response.status_code, 200)
self.assertContains(
response,
'href="/users/login/?next=/catalog/plumbing/kitchen-sink/"',
html=False,
)
self.assertNotContains(response, "data-guest-cart-detail-button", html=False)
def test_header_cart_link_redirects_guest_to_login(self):
response = self.client.get("/catalog/")
self.assertEqual(response.status_code, 200)
self.assertContains(
response,
'href="/users/login/?next=/orders/cart/"',
html=False,
)
def test_detail_page_wrong_category_returns_404(self):
response = self.client.get("/catalog/decor/kitchen-sink/")

View File

@@ -5,6 +5,7 @@ from django.shortcuts import render
from favorites.services import get_user_favorite_item_ids
from items.models import Category, Item, Subcategory
from orders.services import get_user_cart_item_ids
@dataclass
@@ -78,5 +79,6 @@ def detail(request: HttpRequest, category: str, slug: str) -> HttpResponse:
'item': item,
'images': images,
'primary_image': images[0] if images else None,
'cart_item_ids': get_user_cart_item_ids(request.user),
'favorite_item_ids': get_user_favorite_item_ids(request.user),
})