我在一些电子商务商店工作(只是为了学习)。我有父模型Category
和子模型Product
,它有一个字段category
,该字段引用Category
对象Many-To-One relations (ForeignKey)
。方法是从父类进行过滤,例如:Category
检索与给定参数匹配的所有Product
对象。
例如:当我发送一个路由"localhost/api/categories/"
的请求时,我得到了所有的类别和子类别(只是为了更广泛的视野:子类别路由也起作用。如果我向localhost/api/categories/smartphones/
发送请求,它将返回一个包含子类别的响应,这些子类别是smartphones
的子类别,依此类推。现在我想用这种方式实现过滤:当我发送一个路由"localhost/api/categories/smartphones/brand?=apple"
的请求时,它必须返回所有Product
字段等于“apple”的Product
对象。这个模式必须适用于任何类别,所以我不必为可能包含Apple设备的每个类别将apple
硬编码为Category
对象。
我现在的代码(不是所有行都包括在内,但最重要的是):
产品/models.py
class Product(models.Model):
"""Model representing a product."""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
brand = models.ForeignKey('Brand', on_delete=models.CASCADE, related_name='products')
slug = models.SlugField(unique=True, blank=True, default=id)
class Brand(models.Model):
"""A model representing the brand of the product."""
id = models.AutoField(primary_key=True, editable=False)
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True, editable=False)
产品/serializers.py
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
产品/views.py
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
lookup_field = 'slug'
产品/urls.py
router = DefaultRouter()
router.register("", ProductViewSet)
urlpatterns = [
path("", include(router.urls)),
]
类别/models.py
class Category(MPTTModel):
""" Category model inherits from a side application class MPTT designed for more
convenient work with model tree structure """
objects = CategoryManager() # Use of a custom manager defined above
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=120, db_index=True, unique=True)
slug = models.SlugField(unique=True)
parent = TreeForeignKey( # MPTT model Field represents a parent of subcategory (if exists) in tree structure.
"self",
blank=True,
null=True,
related_name="child",
on_delete=models.CASCADE
)
类别/serializers.py
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class CategorySerializer(serializers.ModelSerializer):
child = RecursiveField(many=True, read_only=True)
categories/views.pyclass CategoriesAPIViewSet(viewsets.ModelViewSet):
""" Standard ModelViewSet which implements CRUD with minor changes. """
queryset = Category.objects.all()
serializer_class = CategorySerializer
lookup_field = 'slug'
类别/urls.py
router = SimpleRouter()
router.register("", CategoriesAPIViewSet)
urlpatterns += router.urls
1条答案
按热度按时间wribegjk1#
正如在www.example.com中提到https://www.django-rest-framework.org/api-guide/viewsets/#modelviewset,您可以实现
get_queryset
方法来根据请求提供不同的查询集。您可以使用
self.request.query_params
访问已发送的brand
,网址:https://www.django-rest-framework.org/api-guide/requests/#query_params所以你的方法可能看起来像这样:
或类似:)
根据评论编辑:
如果查询参数是可选的,您可以这样做: