使用HyperlinkedModelSerializer配置不正确的嵌套资源

时间:2015-03-18 15:55:03

标签: django django-rest-framework nested-resources

我选择Django REST Frameworkdrf-nested-routers产品 ProductReports 构建API。以下是相关课程:

# models.py
from django.db import models


class Product(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)


class ProductReport(models.Model):
    user_name = models.CharField(max_length=256, blank=False)
    created_at = models.DateTimeField(auto_now_add=True)
    product = models.ForeignKey('Product', default=1)

...

# serializers.py
from rest_framework import serializers
from models import Product, ProductReport


class ProductSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Product


class ProductReportSerializer(serializers.HyperlinkedModelSerializer):

    product = ProductSerializer()

    class Meta:
        model = ProductReport

...

# views.py
from django.shortcuts import render
from rest_framework import viewsets, mixins
from rest_framework.response import Response
from models import Product, ProductReport
from serializers import ProductSerializer, ProductReportSerializer


class ProductViewSet(mixins.RetrieveModelMixin,
                   mixins.ListModelMixin,
                   viewsets.GenericViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer


class ProductReportViewSet(viewsets.ViewSet):
    queryset = ProductReport.objects.all()
    serializer_class = ProductReportSerializer

    def list(self, request, product_pk=None):
        queryset = self.queryset.filter(product=product_pk)
        serializer = ProductReportSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    def retrieve(self, request, pk=None, product_pk=None):
        queryset = self.queryset.get(pk=pk, product=product_pk)
        serializer = ProductReportSerializer(queryset)
        return Response(serializer.data)

...

# urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from rest_framework import routers
from rest_framework_nested.routers import SimpleRouter, NestedSimpleRouter
from productreports import views

router = routers.SimpleRouter()
router.register(r'products', views.ProductViewSet)

products_router = NestedSimpleRouter(router, r'products', lookup='product')
products_router.register(r'productreports', views.ProductReportViewSet)


urlpatterns = patterns('',
    url(r'^', include(router.urls)),
    url(r'^', include(products_router.urls)),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
)

当我访问http://localhost:8000/products/1/productreports/时,会显示以下错误

  

/ products / 1 / productreports /
不正确配置   无法使用视图名称" productreport-detail"解析超链接关系的URL。您可能未能在API中包含相关模型,或者在此字段上错误地配置了lookup_field属性。

如果设置正确,有一些我不确定的事情:

  • product = models.ForeignKey('Product', default=1)
  • {li> many=True serializer = ProductReportSerializer(queryset, many=True, context={'request': request}) ... 每个产品可以产品报告
  • ProductReportSerializer一般
  • lookup='product'
  • products_router = NestedSimpleRouter(router, r'products', lookup='product')

更新

我注意到只有产品至少一个关联的 productreport 时才会出现错误。如果 productreports 表中不包含特定产品的条目,那么API响应就可以了。

当我检查serializer中的ProductReportViewSet#list时,我得到了:

ProductReportSerializer([
    <ProductReport: ProductReport object>, <ProductReport: ProductReport object>, 
    <ProductReport: ProductReport object>, <ProductReport: ProductReport object>, 
    <ProductReport: ProductReport object>, <ProductReport: ProductReport object>, 

'...(remaining elements truncated)...'], context={'request': <rest_framework.request.Request object>}, many=True):
        url = HyperlinkedIdentityField(view_name='productreport-detail')
        product = ProductSerializer():
            url = HyperlinkedIdentityField(view_name='product-detail')
            created_at = DateTimeField(read_only=True)
        user_name = CharField(max_length=256)
        created_at = DateTimeField(read_only=True)

0 个答案:

没有答案