Django Rest Framework - AssertionError Fix your UR

2020-08-15 01:19发布

I'm trying to return as single object (not a queryset) that is specific to a user without them having to specify an identifier/pk within the requested URL. Each user has an organisation FK.

i.e. http://website/organisation and not http://website/organisation/1

I'm receiving the following error, since it's expecting this identifier: AssertionError: Expected view OrganisationDetail to be called with a URL keyword argument named "user__organisation_id". Fix your URL conf, or set the.lookup_fieldattribute on the view correctly.

How/What do I need to specify when using the RetrieveModelMixin/GenericAPIViewso that it returns a singular object linked by a FK?

My view class:

class OrganisationDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,generics.GenericAPIView):
    serializer_class = OrganisationDetailSerializer
    lookup_field = 'pk' #yes, I know this is the default and there's no need to speciy

    def get_queryset(self):
        return Organisation.objects.filter(pk=self.request.user.organisation_id)

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

Related url: url(r'^api/v1/organisation/$', OrganisationDetail.as_view()),

My model:

class Person(AbstractUser):
    organisation = models.ForeignKey(Organisation, related_name='members', null=True)
    is_admin = models.BooleanField(default=False)
    def __str__(self):
        return self.first_name + " " + self.last_name + " - " + self.email

2条回答
小情绪 Triste *
2楼-- · 2020-08-15 01:55

If you are using mixins, change the lookup_field to the right one

class OrganisationDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,generics.GenericAPIView):

    serializer_class = OrganisationDetailSerializer
    lookup_field = 'members' 

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def patch(self, request, *args, **kwargs):
        return self.partial_update(request, *args, **kwargs)
查看更多
放我归山
3楼-- · 2020-08-15 02:04

You need to override get_object(), not get_queryset() for detail views. You still want the permission checking so I suggest going through the source. First remove your get_queryset() method then try this for starters:

# inside OrganisationDetail
queryset = Organisation.objects.all()

def get_object(self):
    queryset = self.filter_queryset(self.get_queryset())
    # make sure to catch 404's below
    obj = queryset.get(pk=self.request.user.organisation_id)
    self.check_object_permissions(self.request, obj)
    return obj
查看更多
登录 后发表回答