0
votes

I am trying to create an API for custom user model to add a new user using generic views.

I am getting an error and not able to identify the root cause of it. Though the user gets added successfully. But I still recieves a HTTP 500 error in my response.

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

My apiView class is as follows.

class CreateUserView(CreateAPIView):
"""
This view creates a new user
"""
serializer_class = UserSerializer

def perform_create(self, serializer: UserSerializer):
    try:
        serializer.save(
            email=serializer._validated_data['email'],
            first_name=serializer._validated_data['first_name'],
            last_name=serializer._validated_data['last_name'],
            password=make_password(serializer._validated_data['password'])
        )
    except Exception as exception:
        return JsonResponse({
            'success': False,
            'error': 'Error occured in registering user!'
        },
            status=500)

    return JsonResponse({'success': True})

and my serializer class is as below.

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(max_length=128, min_length=8,
                                     style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = User
        fields = ('url', 'id', 'email', 'first_name', 'last_name', 'password',)

and my url patterns file is as follows

urlpatterns = [
    path('api/new_user', CreateUserView.as_view()),
    path('api/login/', obtain_auth_token, name='api-token-auth')
]

Please help me resolving this.

1

1 Answers

0
votes

You can circumvent the need for lookup_fields by using rest_framework view sets.

Here is an example

CreateUserView

...

from rest_framework import viewsets

...

class CreateUserView(viewsets.ModelViewSet):

    serializer_class = UserSerializer

    class Meta:
        model = User

Url patterns


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/new_user', CreateUserView.as_view({'post': 'create'}))
]

This will give you functionality straight out of the box.

Further customization:

  1. The model viewset provides responses for you but if you want to customize your response as in your example, you can override the create method in CreateUserView like this:
class CreateUserView(viewsets.ModelViewSet):

    serializer_class = UserSerializer

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return JsonResponse({'success': True})

    class Meta:
        model = User