Another could not resolve URL for hyperlinked relationship error
Question:
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": "[email protected]",
"first_name": "s",
"last_name": "d",
"password": "f"
}
and server return:
{
"results": {
"email": "[email protected]",
"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?
Answers:
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:
- Remove the
url
field from the serializer
- 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"
}
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": "[email protected]",
"first_name": "s",
"last_name": "d",
"password": "f"
}
and server return:
{
"results": {
"email": "[email protected]",
"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 thelookup_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:
- Remove the
url
field from the serializer - 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"
}