默认的HyperlinkedModelSerializer找不到端点

时间:2020-04-09 13:07:49

标签: django django-rest-framework

我试图将我的ModelSerializer更改为HyperlinkedModelSerializer,以包含默认Browsable API的ListView中列出的每个对象的URL。

根据文档,由于我使用默认的“ pk”进行查找,因此我只更改了从以下项继承序列化程序的类:

# class SeasonSerializer(serializers.ModelSerializer):
class SeasonSerializer(serializers.HyperlinkedModelSerializer):

    # url = serializers.HyperlinkedIdentityField(
    #     view_name='season', lookup_field='pk') ---> Not needed according to docs but have also tried with this

    class Meta:
        model = Season
        fields = ('id', 'url', 'years', 'active')

并在视图中实例化上下文时添加上下文:

class SeasonListView(APIView):

    def get(self, request, *args, **kwargs):
        queryset = Season.objects.all().order_by('years')
        serializer = SeasonSerializer(
            queryset, many=True, context={'request': request})
        print('INFO: ', serializer)
        permission_classes = [ ]
        authentication_classes = [ ]
        return Response({"Seasons": serializer.data})

class SeasonDetailView(APIView):

    def get(self, request, *args, **kwargs):
        pk = kwargs['pk']
        season = get_object_or_404(Season, pk=pk)
        serializer = SeasonSerializer(season, context={'request': request})
        # print('Data: ', serializer.data) --> this breaks
        return Response(serializer.data)

我的端点与使用ModelSerializer时的端点相同:

urlpatterns = [
    path(r'seasons/', SeasonListView.as_view(), name='season-list'),
    path(r'seasons/<int:pk>/', SeasonDetailView.as_view(), name='season-detail'),
]

错误如下:

对于http://localhost:8000/api/seasons/1/

Exception Type: ImproperlyConfigured
Exception Value:    
Could not resolve URL for hyperlinked relationship using view name "season-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

对于http://localhost:8000/api/seasons/

Exception Type: ImproperlyConfigured
Exception Value:    
Could not resolve URL for hyperlinked relationship using view name "season-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

我在这里想念什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

很多天后,我认为我发现了问题,所以我在这里发帖,以防我可以节省很多时间!

问题基本上出在您处理路线的方式上。

如果(您正在为每个应用程序使用路由器):
然后,当您在路由器中注册并在序列化程序中手动定义 url字段时,必须添加对象的基名。不要忘记添加应用程序的名称,例如“ app:model”。例如:

router.register(r'seasons', SeasonViewSet, basename='seasons')
class SeasonSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name="accounts:seasons-detail")
    class Meta:
        model = Season
        fields = ('url', 'id', '...')

如果(您正在使用1个路由器嵌套来自其他应用程序的其余路由器):

就像他们在here中所做的那样。 然后,您需要从网址字段的“ app:model”定义中删除该应用。

我强烈建议使用django-extesions来使用python manage.py show_urls,以了解项目中可用的端点。
多亏了它,我才能够弄清楚到底发生了什么。当我添加API根目录时,请看一下比较。

(base) ➜  Betcomm git:(master) ✗ docker-compose exec app python manage.py show_urls | grep api/

/api/accounts/profiles/ accounts.views.ProfileViewSet   accounts:profiles-list
/api/accounts/profiles/<pk>/    accounts.views.ProfileViewSet   accounts:profiles-detail
/api/accounts/season-profiles/  accounts.views.SeasonProfileViewSet accounts:season-profiles-list
/api/accounts/season-profiles/<pk>/ accounts.views.SeasonProfileViewSet accounts:season-profiles-detail
/api/accounts/users/    accounts.views.UserViewSet  accounts:users-list
/api/accounts/users/<pk>/   accounts.views.UserViewSet  accounts:users-detail
/api/seasons/seasons/   seasons.views.SeasonViewSet seasons:seasons-list
/api/seasons/seasons/<pk>/  seasons.views.SeasonViewSet seasons:seasons-detail


(base) ➜  Betcomm git:(master) ✗ docker-compose exec app python manage.py show_urls | grep api/

/api/   rest_framework.routers.APIRootView  api-root
/api/\.<format>/    rest_framework.routers.APIRootView  api-root
/api/profiles/  accounts.views.ProfileViewSet   profiles-list
/api/profiles/<pk>/ accounts.views.ProfileViewSet   profiles-detail
/api/profiles/<pk>\.<format>/   accounts.views.ProfileViewSet   profiles-detail
/api/profiles\.<format>/    accounts.views.ProfileViewSet   profiles-list
/api/season-profiles/   accounts.views.SeasonProfileViewSet seasonprofiles-list
/api/season-profiles/<pk>/  accounts.views.SeasonProfileViewSet seasonprofiles-detail
/api/season-profiles/<pk>\.<format>/    accounts.views.SeasonProfileViewSet seasonprofiles-detail
/api/season-profiles\.<format>/ accounts.views.SeasonProfileViewSet seasonprofiles-list
/api/seasons/   seasons.views.SeasonViewSet seasons-list
/api/seasons/<pk>/  seasons.views.SeasonViewSet seasons-detail
/api/seasons/<pk>\.<format>/    seasons.views.SeasonViewSet seasons-detail
/api/seasons\.<format>/ seasons.views.SeasonViewSet seasons-list
/api/users/ accounts.views.UserViewSet  users-list
/api/users/<pk>/    accounts.views.UserViewSet  users-detail
/api/users/<pk>\.<format>/  accounts.views.UserViewSet  users-detail
/api/users\.<format>/   accounts.views.UserViewSet  users-list