from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpRequest, HttpResponse, JsonResponse from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.http import url_has_allowed_host_and_scheme from django.views.decorators.http import require_POST from favorites.models import Favorite from items.models import Item def wants_json_response(request: HttpRequest) -> bool: return ( request.headers.get("x-requested-with") == "XMLHttpRequest" or "application/json" in request.headers.get("accept", "") ) @login_required def index(request: HttpRequest) -> HttpResponse: favorite_records = ( Favorite.objects.filter(user=request.user) .select_related("item__category", "item__subcategory") .prefetch_related("item__images") .order_by("-created_at", "-id") ) items = [favorite.item for favorite in favorite_records] return render(request, "favorites/index.html", { "items": items, "favorite_count": len(items), "favorite_item_ids": {item.id for item in items}, }) @login_required @require_POST def toggle(request: HttpRequest) -> HttpResponse: item_id = request.POST.get("item_id") item = get_object_or_404(Item, pk=item_id) favorite = Favorite.objects.filter(user=request.user, item=item).first() if favorite: favorite.delete() is_favorite = False message = f"Товар «{item.name}» удалён из избранного." else: Favorite.objects.create(user=request.user, item=item) is_favorite = True message = f"Товар «{item.name}» добавлен в избранное." favorite_count = Favorite.objects.filter(user=request.user).count() next_url = request.POST.get("next") or reverse("favorites:index") if wants_json_response(request): return JsonResponse({ "item_id": item.pk, "is_favorite": is_favorite, "favorite_count": favorite_count, "message": message, }) messages.success(request, message) if not url_has_allowed_host_and_scheme( next_url, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ): next_url = reverse("favorites:index") return redirect(next_url)