【问题标题】:Return id of new Item created with POST using ModelSerializer and ModelViewSet in Django Rest Framework在 Django Rest Framework 中使用 ModelSerializer 和 ModelViewSet 返回使用 POST 创建的新项目的 id
【发布时间】:2021-01-26 20:38:06
【问题描述】:

在 Django Rest Framework 中创建 Post 后,我想获得新的 id 作为响应。

预期功能: 用户获得一个 json 响应,其中包含指向创建的新项目的超链接。

发布

{
    "label": "BMW M3",
    "price": 5000.00
}

回复:

 {
        "id-url": "www.website.com/api/products/id/"
    }

我知道这个主题已经通过各种方式进行了讨论,但我正在寻找一个使用 ModelSerializer 的最小(但完整)示例,我还没有找到这个,因此我的问题。

我的模特:

class Product(models.Model):
    label = models.CharField(max_length=50, blank=True, null=True)
    price = models.FloatField(blank=True, null=True)

我的序列化器:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

我的看法:

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

我的网址:

router = routers.DefaultRouter()
router.register('products', ProductViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

尝试:

我尝试过的一些参考资料。 这是类似的问题,但答案似乎不完整ex_0 我可以重新创建这个ex_1,但不给我 id

【问题讨论】:

  • 你现在得到了什么?你的模型看起来怎么样?
  • 这可能对你有帮助,Relationships & Hyperlinked APIs
  • 谢谢,虽然超链接在这里是次要的,但它最重要的是我正在寻找的 id(我将创建一个超链接),我修改了问题以反映这一点。
  • 为什么example 1 看起来不完整?尝试后会发生什么?
  • 嗨,将 'id = serializers.IntegerField(source='pk')' 添加到序列化程序不会创建带有 id 的 json 响应。尝试时我也得到一个错误,“需要一个有效的整数。”理想情况下,我正在寻找一个完整的(功能性)答案。作为新手,不完整的sn-ps代码有点令人困惑,因为解释中遗漏了很多内容。

标签: python django django-rest-framework django-rest-viewsets


【解决方案1】:

感谢这篇文章:Get the id of the object recently created Django Rest Framework 我设法想出了一个潜在的解决方案。它似乎有效,但我有点不确定它是否是“最佳”方式。

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

    def create(self, request):
        serializer = ProductSerializer(data=request.data)
        if serializer.is_valid():
            product = serializer.save()
            pid = product.id
            product.url = f'http://localhost:8000/api/products/{pid}/'
            data = serializer.data
            data.update({'id-url':product.url}) # attaching key-value to the dictionary
            return Response(data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

【讨论】:

    【解决方案2】:
    class ProductViewSet(viewsets.ModelViewSet):
        queryset = Product.objects.all()
        serializer_class = ProductSerializer
    
        def create(self, request, *args, **kwargs):
            response = super(ProductViewSet, self).create(request, *args, **kwargs)
            # response.data has everything specified in your serializer; it seems fine to clobber it
            # alternatively, you could add to it: response.data['foo']='baz'
            response.data = {'id-url': f'http://localhost:8000/api/products/{response.data['id']}/'}
            return response
    

    【讨论】:

      猜你喜欢
      • 2019-04-26
      • 2018-01-18
      • 2013-09-19
      • 2021-02-06
      • 2015-11-16
      • 2021-12-21
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多