断言错误:`HyperlinkedIdentityField` 需要序列化程序上下文中的请求 [英] AssertionError: `HyperlinkedIdentityField` requires the request in the serializer context

查看:15
本文介绍了断言错误:`HyperlinkedIdentityField` 需要序列化程序上下文中的请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一种多对多关系,一个人可以在多个俱乐部,一个俱乐部可以有很多人.我为以下逻辑添加了 models.pyserializers.py,但是当我尝试在命令提示符中对其进行序列化时,出现以下错误 - 我在做什么错在这里?我什至没有 HyperlinkedIdentityField

I want to create a many-to-many relationship where one person can be in many clubs and one club can have many persons. I added the models.py and serializers.py for the following logic but when I try to serialize it in the command prompt, I get the following error - What am I doing wrong here? I don't even have a HyperlinkedIdentityField

Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:Usersusercorrlibsite-packages
est_frameworkserializers.py", line 503, in data
ret = super(Serializer, self).data
File "C:Usersusercorrlibsite-packages
est_frameworkserializers.py", line 239, in data
self._data = self.to_representation(self.instance)
File "C:Usersusercorrlibsite-packages
est_frameworkserializers.py", line 472, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "C:Usersusercorrlibsite-packages
est_framework
elations.py", line 320, in to_representation"the serializer." % self.__class__.__name__
AssertionError: `HyperlinkedIdentityField` requires the request in the serializer context. Add `context={'request': request}` when instantiating the serializer.

models.py

class Club(models.Model):
    club_name = models.CharField(default='',blank=False,max_length=100)

class Person(models.Model):
    person_name = models.CharField(default='',blank=False,max_length=200)
    clubs = models.ManyToManyField(Club)

serializers.py

class ClubSerializer(serializers.ModelSerializer):
    class Meta:
        model = Club
        fields = ('url','id','club_name','person')

class PersonSerializer(serializers.ModelSerializer):
    clubs = ClubSerializer()
    class Meta:
        model = Person
        fields = ('url','id','person_name','clubs')

views.py

class ClubDetail(generics.ListCreateAPIView):
serializer_class = ClubSerializer

def get_queryset(self):
     club = Clubs.objects.get(pk=self.kwargs.get('pk',None))
     persons = Person.objects.filter(club=club)
     return persons

class ClubList(generics.ListCreateAPIView):
    queryset = Club.objects.all()
    serializer_class = ClubSerializer


class PersonDetail(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = PersonSerializer


def get_object(self):
    person_id = self.kwargs.get('pk',None)
    return Person.objects.get(pk=person_id) 

检查创建的序列化程序给了我这个 -

Inspecting the created serializer gives me this -

PersonSerializer(<Person: fd>):
url = HyperlinkedIdentityField(view_name='person-detail')
id = IntegerField(label='ID', read_only=True)
person_name = CharField(max_length=200, required=False)
clubs = ClubSerializer():
    url = HyperlinkedIdentityField(view_name='club-detail')
    id = IntegerField(label='ID', read_only=True)
    club_name = CharField(max_length=100, required=False)

但是 serializer.data 给了我错误

编辑

我意识到错误可能是由于 url 模式,所以我添加了以下 url 模式,但我仍然收到错误 -

I realized the error could be because of url patterns, so I added the following url patterns but I still get the error -

urlpatterns = format_suffix_patterns([
url(r'^$', views.api_root),
url(r'^clubs/$',
    views.ClubList.as_view(),
    name='club-list'),
 url(r'^clubs/(?P<pk>[0-9]+)/persons/$',
    views.ClubDetail.as_view(),
    name='club-detail'),
url(r'^person/(?P<pk>[0-9]+)/$',
    views.PersonDetail.as_view(),
    name='person-detail'),
])

推荐答案

您收到此错误是因为 HyperlinkedIdentityField 期望在 context<中接收 request/code> 的序列化程序,因此它可以构建绝对 URL.当您在命令行上初始化序列化程序时,您无权访问请求,因此会收到错误消息.

You're getting this error as the HyperlinkedIdentityField expects to receive request in context of the serializer so it can build absolute URLs. As you are initializing your serializer on the command line, you don't have access to request and so receive an error.

如果您需要在命令行上检查序列化程序,则需要执行以下操作:

If you need to check your serializer on the command line, you'd need to do something like this:

from rest_framework.request import Request
from rest_framework.test import APIRequestFactory

from .models import Person
from .serializers import PersonSerializer

factory = APIRequestFactory()
request = factory.get('/')


serializer_context = {
    'request': Request(request),
}

p = Person.objects.first()
s = PersonSerializer(instance=p, context=serializer_context)

print s.data

您的 url 字段类似于 http://testserver/person/1/.

Your url field would look something like http://testserver/person/1/.

这篇关于断言错误:`HyperlinkedIdentityField` 需要序列化程序上下文中的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆