Django "<!DOCTYPE "..." не является валидным JSON модалом быстрого просмотра

Я пытаюсь создать сайт электронной коммерции, где я хочу, чтобы пользователи могли видеть quickview продукт, не переходя на страницу product_detail. Поэтому я хочу динамически загружать все подробности о товаре в модальном окне quickview. Может ли кто-нибудь помочь мне с этими ошибками? Заранее спасибо!

Хорошо, итак, мой models.py:

Мой views.py:

class BusinessDetailView(View):
    def get(self, request, business_slug):
        business = get_object_or_404(Business, business_slug=business_slug)
        products = business.products.all()
        services = business.services.all()
        opening_hours = business.opening_hours.all()
        return render(request, 'business/business_detail.html', {'business': business, 'products': products, 'opening_hours': opening_hours, 'services': services})

class ProductDetailView(View):
    def get(self, request, business_slug=None, product_slug=None):
        if request.is_ajax():
            return self.ajax_get(request, business_slug, product_slug)
        
        business = get_object_or_404(Business, business_slug=business_slug)
        product = get_object_or_404(Product, product_slug=product_slug, business=business)
        
        color_variations = Variation.objects.filter(product=product, name='color')
        size_variations = Variation.objects.filter(product=product, name='size')

        context = {
            'product': product,
            'business': business,
            'color_variations': color_variations,
            'size_variations': size_variations,
        }

        return render(request, 'business/product_detail.html', context)

    def ajax_get(self, request, business_slug, product_slug):
        business = get_object_or_404(Business, business_slug=business_slug)
        product = get_object_or_404(Product, product_slug=product_slug, business=business)

        color_variations = Variation.objects.filter(product=product, name='color')
        size_variations = Variation.objects.filter(product=product, name='size')
        
        product_data = {
            'id': product.id,
            'name': product.name,
            'price': float(product.price),
            'description': product.description,
            'images': [product.image.url, product.image2.url] if product.image and product.image2 else [],
            'color_variations': list(color_variations.values('id', 'values__id', 'values__value', 'values__image')),
            'size_variations': list(size_variations.values('id', 'values__id', 'values__value')),
            'sku': product.product_slug,
            'categories': [product.business.business_name],
            'tags': [tag.name for tag in product.tags.all()] if hasattr(product, 'tags') else []
        }
        return JsonResponse(product_data)

Мой urls.py:

    path('business/<slug:business_slug>/', views.BusinessDetailView.as_view(), name='business_detail'),
    path('business/<slug:business_slug>/edit/', views.edit_business, name='edit_business'),
    path('business/<slug:business_slug>/product/create/', views.ProductCreateView.as_view(), name='product_create'),
    path('business/<slug:business_slug>/product/<slug:product_slug>/', views.ProductDetailView.as_view(), name='product_detail'),
    path('ajax/product/<slug:business_slug>/<slug:product_slug>/', views.ProductDetailView.as_view(), name='ajax_product_detail'),

Мой main.js:

Мой бизнес_деталь.html:

Однако когда я нажимаю кнопку быстрого просмотра, в консоли появляется сообщение:

Quick View Button: <div class=​"quick-view-btn w-full text-button-uppercase py-2 text-center rounded-full duration-300 bg-white hover:​bg-black hover:​text-white" data-product-slug=​"jacket" data-business-slug=​"lululemon">​…​</div>​
lululemon/:3551 Product Slug: jacket
lululemon/:3552 Business Slug: lululemon
main.js:1377 Quick View Button: <div class=​"quick-view-btn w-full text-button-uppercase py-2 text-center rounded-full duration-300 bg-white hover:​bg-black hover:​text-white" data-product-slug=​"jacket" data-business-slug=​"lululemon">​…​</div>​
main.js:1378 Product Slug: jacket
main.js:1379 Business Slug: lululemon
lululemon/:3559 
        
        
       GET http://127.0.0.1:8000/ajax/product/jacket/?business_slug=lululemon 404 (Not Found)
(anonymous) @ lululemon/:3559Understand this error
lululemon/:3561 Response status: 404
lululemon/:3570 Error: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
(anonymous) @ lululemon/:3570
Promise.catch (async)
(anonymous) @ lululemon/:3569Understand this error
main.js:1388 Response status: 200
main.js:1400 Error: SyntaxError: Unexpected token '<', "





<!DOCTYPE "... is not valid JSON

На моем терминале написано:

[02/Jun/2024 07:25:39] "GET /business/lululemon/assets/data/Product.json HTTP/1.1" 404 8444
Not Found: /ajax/product/jacket/
[02/Jun/2024 07:25:41] "GET /ajax/product/jacket/?business_slug=lululemon HTTP/1.1" 404 8375
[02/Jun/2024 07:25:41] "GET /ajax/product/lululemon/jacket/ HTTP/1.1" 200 271499

Измените ваш main.js на:

Ваш вызов fetch("/ajax/product/•••") делает GET-запрос к URLconf "ajax_product_detail". Представление на этом URL - ProductDetailView. Это представление, основанное на классе, поэтому GET-запрос к этому представлению вызовет подпрограмму get в этом классе. Эта подпрограмма отображает шаблон "business/product_detail.html".

Теперь вы видите проблему? Вы, наверное, думаете, что будет вызвана подпрограмма ajax_get. Это не так. Лучше вынести эту подпрограмму в отдельное представление:

class AjaxProductDetailView(View):
    def get(self, request, business_slug, product_slug):
        business = get_object_or_404(Business, business_slug=business_slug)
        product = get_object_or_404(Product, product_slug=product_slug, business=business)

        color_variations = Variation.objects.filter(product=product, name='color')
        size_variations = Variation.objects.filter(product=product, name='size')
        
        product_data = {
            'id': product.id,
            'name': product.name,
            'price': float(product.price),
            'description': product.description,
            'images': [product.image.url, product.image2.url] if product.image and product.image2 else [],
            'color_variations': list(color_variations.values('id', 'values__id', 'values__value', 'values__image')),
            'size_variations': list(size_variations.values('id', 'values__id', 'values__value')),
            'sku': product.product_slug,
            'categories': [product.business.business_name],
            'tags': [tag.name for tag in product.tags.all()] if hasattr(product, 'tags') else []
        }
        return JsonResponse(product_data)
path('ajax/product/<slug:business_slug>/<slug:product_slug>/', views.AjaxProductDetailView.as_view(), name='ajax_product_detail')

Теперь GET-запрос будет правильно обработан правильным представлением.

Я предложил это решение, потому что понял, что ваше представление не является специфичным для какой-либо модели.

В вашем файле views.py метод ajax_get класса ProductDetailView возвращает JsonResponse с данными о продукте. Однако url /ajax/product/jacket/?business_slug=lululemon не обрабатывается Django должным образом, что приводит к ошибке 404.

Обновите файл main.js:

fetch(`/ajax/product/${businessSlug}/${productSlug}/`)
Вернуться на верх