Проблема Django Rest API с получением корректной информации из урлов. Это отношения типа "дедушка - бабушка - родитель - ребенок". Как их правильно сопоставить?
Я застрял на этой проблеме около 9 часов и испытываю трудности с пониманием отношения Grandparent - Parent - Child с отношением One to Many (внешний ключ) в Django.
В настоящее время я создаю сайт электронной коммерции и пытаюсь отобразить информацию 4 различными способами для получения с моего фронтенда React.
У меня есть 3 модели настроенные: Категория Подкатегория (внешний ключ к категории) Продукты (внешний ключ к подкатегории)
Вот такой результат я пытаюсь создать в моих файлах urls/views/serializer: По какой-то причине я могу успешно получить данные на гранулированном уровне для одного продукта, но как только я начинаю подниматься по вложенным моделям, я сталкиваюсь со следующими ошибками:
Желаемый результат
I have api/ included in the core urls folder already.
I want JSON to display the information like this.
# URLSearch api/Category/
# Category -
# |
# Subcategory 1 -
# |
# Product 1
# Product 2
# Subcategory 2 -
# |
# Product 1
# Proudct 2
I also want JSON to display the information like this.
# URLSearch api/Category/Subcategory/
# Category -
# |
# Subcategory -
# |
# Product 1
# Product 2
Ошибки
Ошибка 1:
Получена ошибка AttributeError при попытке получить значение для поля slug
на сериализаторе SubcategoryListSerializer
.
Поле сериализатора может быть названо неверно и не совпадать с атрибутом или ключом экземпляра QuerySet
.
Оригинальный текст исключения был: 'QuerySet' object has no attribute 'slug'.
Ошибка 2: Returns Wrong Object piggies back off issue above - I deleted my code to clean it file as I had been attempting this for 10+ hours so there is currently a place holder route there.
Urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from api import views
urlpatterns = [
path('search/<slug:category_slug>/<slug:subcategory_slug>/',
views.SubcategoryListView.as_view()), #Error 1
path('search/<slug:category_slug>/', views.AllProductsListView.as_view()), # Error 2
path('all-products/', views.AllProductsListView.as_view()), # Good
path('search/<slug:category_slug>/<slug:subcategory_slug>/<slug:product_slug>',
views.ProductDetail.as_view()), # WORKS
# path('all-products/', views.AllProductsListView.as_view())
]
Models.py
from django.db import models
import uuid
# Create your models here.
class Category(models.Model):
slug = models.SlugField(
primary_key=True, max_length=50, null=False, unique=True)
class Meta:
ordering = ('slug',)
def __str__(self):
return self.slug
def get_absolute_url(self):
return f'/{self.slug}/'
class Subcategory(models.Model):
slug = models.SlugField(
primary_key=True, max_length=50, null=False, unique=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
class Meta:
ordering = ('category',)
def __str__(self):
return self.slug
def get_absolute_url(self):
return f'/{self.category.slug}/{self.slug}/'
class Products(models.Model):
subcategory = models.ForeignKey(Subcategory, on_delete=models.CASCADE)
newAdd = models.BooleanField(default=False)
name = models.CharField(max_length=200)
slug = models.SlugField(
primary_key=True, max_length=50, null=False, unique=True)
imageOne = models.CharField(max_length=100)
imageTwo = models.CharField(max_length=100, null=True)
imageThree = models.CharField(max_length=100, null=True)
colors = models.CharField(max_length=300) # This is going to be a list
price = models.FloatField()
dateCreated = models.DateField(auto_now_add=True)
class Meta:
ordering = ('-dateCreated',)
def __str__(self):
return self.slug
def get_absolute_url(self):
return f'/{self.subcategory.category.slug}/{self.subcategory.slug}/{self.slug}'
Виды
from django.shortcuts import render
from .serializers import AllProductsSerializer, CategorySerializer, SubcategoryListSerializer, ProductsSerializer, SubcategorySerializer
from rest_framework import viewsets, generics, views, response
from products.models import Products, Subcategory, Category
# Create your views here.
class ProductDetail(views.APIView):
def get_object(self, category_slug, subcategory_slug, product_slug):
obj = Products.objects.filter(subcategory__category__slug=category_slug).filter(
subcategory=subcategory_slug).get(slug=product_slug)
return obj
def get(self, request, category_slug, subcategory_slug, product_slug):
print(request)
product = self.get_object(
category_slug, subcategory_slug, product_slug)
serializer = ProductsSerializer(product)
return response.Response(serializer.data)
class SubcategoryListView(views.APIView):
def get_object(self, category_slug, subcategory_slug):
obj = Products.objects.filter(
subcategory__category__slug=category_slug)
return obj
def get(self, request, category_slug, subcategory_slug):
products = self.get_object(category_slug, subcategory_slug)
serializer = SubcategoryListSerializer(products)
return response.Response(serializer.data)
class AllProductsListView(generics.ListAPIView):
serializer_class = AllProductsSerializer
queryset = Products.objects.all()
class CategoryListView(generics.ListCreateAPIView):
queryset = Products.objects.all()
serializer_class = Category
Сериализаторы
from rest_framework import serializers
from products.models import Products, Category, Subcategory
class ProductsSerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = (
'newAdd',
'name',
'slug',
'imageOne',
'price',
'dateCreated',
'get_absolute_url',
)
class SubcategoryListSerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = ('__all__')
class SubcategorySerializer(serializers.ModelSerializer):
items = SubcategoryListSerializer(many=True, read_only=True)
class Meta:
model = Subcategory
fields = (
'slug',
'items'
'get_absolute_url',
)
class AllProductsSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('__all__')
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Products
fields = ('__all__')