简体   繁体   中英

Another could not resolve URL for hyperlinked relationship error

Yes I know a similar question has been asked many times, but I am sorry none of answers have really helped me or I missed something important.

I want to make registration when posted data from client are in format:

{
    "email": "asouausdhnsabnsmsd.s@s.com",
    "first_name": "s",
    "last_name": "d",
    "password": "f"
}

and server return:

{
    "results": {
        "email": "asouausdhnsabnsmsd.s@s.com",
        "first_name": "s",
        "last_name": "d"
    }
}

When I post data I got:

ImproperlyConfigured at /api/register Could not resolve URL for hyperlinked relationship using view name "customuser-detail". You may have failed to include the related model in your API, or incorrectly configured the lookup_field attribute on this field.

So I have serializers.py like:

class RegisterUserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = CustomUser
        fields = ('url', 'email', 'first_name', 'last_name', 'password')
        write_only_fields = ('password',)

    def create(self, validated_data):
        user = CustomUser.objects.create(**validated_data)
        try:
            user.set_password(user.password)
            user.save()
            return user
        except KeyError:
            return user


class RegisterUserRetrieveSerializer(serializers.Serializer):
    results = RegisterUserSerializer(source='*')

Then api viewsets in views.py:

class RegisterUserViewSet(mixins.CreateModelMixin,
                          viewsets.GenericViewSet):
    permission_classes = (AllowAny,)
    parser_classes = (parsers.JSONParser,)
    serializer_class = serializers.RegisterUserSerializer
    model = CustomUser

    def create(self, request):
        serializer = serializers.RegisterUserSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            user = serializer.save()
            serializer = serializers.RegisterUserRetrieveSerializer(user, context={'request': request})
            results = serializer.data
            return Response(results, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

And urls.py:

router = routers.DefaultRouter()
router_without_trailing_slashes = routers.DefaultRouter(trailing_slash=False)
router.register(r'register', RegisterUserViewSet, base_name='customuser')
router_without_trailing_slashes.register(r'register', RegisterUserViewSet, base_name='customuser')

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^templates/', include('core.main.urls'), name='templates'),

    url(r'^api/', include(router_without_trailing_slashes.urls)),
    url(r'^api/', include(router.urls)),
]

The new user is saved correctly to db so I suppose the error is somehow connected with RegisterUserRetrieveSerializer. Any ideas?

It looks like the problem is that you are including the url field in the serializer, but DRF is unable to generate that url, because there is no detail view for the serializer.

There are two options:

  1. Remove the url field from the serializer
  2. Add mixins.RetrieveModelMixin to the ViewSet, so that the serializer can generate a detail url for the instance

Error is happening due to the 'url' field included in fields list in serializer.

After adding 'url' field you need to define the view_name and lookup_field for that url in extra_kwargs.

class RegisterUserSerializer(serializers.HyperlinkedModelSerializer):  
    class Meta:
        model = CustomUser
        fields = ('url', 'email', 'first_name', 'last_name', 'password')
        write_only_fields = ('password',)
        extra_kwargs = {
               "url":{
                  "view_name": "customuser-detail",
                  "lookup_field": "pk"
               }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM