Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AssertionError: `HyperlinkedIdentityField` requires the request in the serializer context

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:\Users\user\corr\lib\site-packages\rest_framework\serializers.py", line 503, in data ret = super(Serializer, self).data File "C:\Users\user\corr\lib\site-packages\rest_framework\serializers.py", line 239, in data self._data = self.to_representation(self.instance) File "C:\Users\user\corr\lib\site-packages\rest_framework\serializers.py", line 472, in to_representation ret[field.field_name] = field.to_representation(attribute) File "C:\Users\user\corr\lib\site-packages\rest_framework\relations.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) 

but serializer.data gives me the error

Edit

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'), ]) 
like image 623
qwertp Avatar asked Dec 23 '15 14:12

qwertp


1 Answers

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 

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

like image 177
Ashley 'CptLemming' Wilson Avatar answered Sep 23 '22 09:09

Ashley 'CptLemming' Wilson