如何使用 Django REST 框架的 ModelViewSets 实现 HATEOAS 风格的链接?

布雷迪·迪恩

我有这个产品型号

import uuid
from django.db import models


class Product(models.Model):
    """Product in the store."""

    title = models.CharField(max_length=120)
    description = models.TextField(blank=True)
    price = models.DecimalField(decimal_places=2, max_digits=10)
    inventory = models.IntegerField(default=0)
    uuid = models.UUIDField(default=uuid.uuid4, editable=False)

    def __str__(self):
        return f'{self.title}'

我为它定义了一个序列化程序

from rest_framework import serializers
from .models import Product


class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['title', 'description', 'price', 'inventory', 'uuid']

这是我的观点

from rest_framework import viewsets
from .serializers import ProductSerializer

from .models import Product


class ProductViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    lookup_field = 'uuid'

要开始这个问题,请记住,此视图是在 上路由的/store/products/现在,例如我可以执行 GEThttp://localhost/store/products/并返回

[
    {
        "title": "Computer",
        "description": "",
        "price": "50.00",
        "inventory": 10,
        "uuid": "2d849f18-7dea-42b9-9dac-2ea8a17444c2"
    }
]

但我希望它返回类似的东西


[
    {
        "href": "http://localhost/store/products/2d849f18-7dea-42b9-9dac-2ea8a17444c2"
    }
]

然后http://localhost/store/products/2d849f18-7dea-42b9-9dac-2ea8a17444c2返回

{
    "title": "Computer",
    "description": "",
    "price": "50.00",
    "inventory": 10,
    "uuid": "2d849f18-7dea-42b9-9dac-2ea8a17444c2"
}

因为它已经这样做了。这是否可以使用内置序列化,或者我如何定义一个这样做的?我玩过这处list_serializer_class房产,但我什么也做不了。

蒂姆·尼伯格

超链接序列化程序可以返回指向另一个视图或同一视图集的另一部分的属性:

序列化器:

from rest_framework import serializers

class ProductListSerializer(serializers.ModelSerializer):
    href = serializers.HyperlinkedIdentityField(view_name='<app_name>:product-detail', lookup_field='uuid')

    class Meta:
        model = Product
        fields = ['href']

class ProductDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['title', 'description', 'price', 'inventory', 'uuid']

网址:

from rest_framework import routers

app_name ='<app_name>'

router = routers.DefaultRouter()
router.register(r'products', ProductViewSet, basename='product')
urlpatterns = router.urls

视图集:

from rest_framework.response import Response
from django.shortcuts import get_object_or_404

class ProductViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Product.objects.all()
    lookup_field = 'uuid'

    def list(self, request, **kwargs):
        serializer = ProductListSerializer(self.get_queryset(), many=True, context={'request': request})
        return Response(serializer.data)

    def retrieve(self, request, uuid=None, *args, **kwargs):
        record = get_object_or_404(self.get_queryset(), uuid=uuid)
        serializer = ProductDetailSerializer(record)
        return Response(serializer.data)

编辑:更新为使用 uuid,而不是 pk,如您的示例所示

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章