manosim / manosim/django-rest-framework-docs

Error when using custom user model

Open
#146 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
641
Forks
178
PR merge metrics
No merged PRs in 30d

Description

I get the following error on the documentation root page:
ImproperlyConfigured: Field name usernameis not valid for modelCustomUser.

I imagine this has something to do with my custom user model, where I have disabled the username field by setting USERNAME_FIELD = 'email' in the model. The rest API works fine and it is only when setting url(r'^api/v1/', include('rest_framework_docs.urls')), that I get the problem at /api/v1/

The traceback indicates it is coming from the following lines in api_endpoint.py:

fields = [{
                "name": key,
                "type": str(field.__class__.__name__),
                "required": field.required
            } for key, field in serializer().get_fields().items()]

However, I can enter the python shell, get an instance of the serializer and run this code manually just fine. So I'm now at a loss as to what is causing this...

The full traceback is:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
    return self.application(environ, start_response)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 177, in __call__
    response = self.get_response(request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 230, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 289, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
  File "/usr/local/lib/python2.7/site-packages/django_extensions/management/technical_response.py", line 6, in null_technical_500_response
    six.reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/utils/decorators.py", line 184, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/django/views/generic/base.py", line 157, in get
    context = self.get_context_data(**kwargs)
  File "/usr/local/lib/python2.7/site-packages/rest_framework_docs/views.py", line 17, in get_context_data
    docs = ApiDocumentation()
  File "/usr/local/lib/python2.7/site-packages/rest_framework_docs/api_docs.py", line 21, in __init__
    self.get_all_view_names(root_urlconf.urlpatterns)
  File "/usr/local/lib/python2.7/site-packages/rest_framework_docs/api_docs.py", line 27, in get_all_view_names
    self.get_all_view_names(urlpatterns=pattern.url_patterns, parent_pattern=parent_pattern)
  File "/usr/local/lib/python2.7/site-packages/rest_framework_docs/api_docs.py", line 29, in get_all_view_names
    api_endpoint = ApiEndpoint(pattern, parent_pattern)
  File "/usr/local/lib/python2.7/site-packages/rest_framework_docs/api_endpoint.py", line 19, in __init__
    self.fields = self.__get_serializer_fields__()
  File "/usr/local/lib/python2.7/site-packages/rest_framework_docs/api_endpoint.py", line 54, in __get_serializer_fields__
    } for key, field in serializer().get_fields().items()]
  File "/usr/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 1000, in get_fields
    field_name, info, model, depth
  File "/usr/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 1135, in build_field
    return self.build_unknown_field(field_name, model_class)
  File "/usr/local/lib/python2.7/site-packages/rest_framework/serializers.py", line 1242, in build_unknown_field
    (field_name, model_class.__name__)
ImproperlyConfigured: Field name `username` is not valid for model `CustomUser`.

My serializer:

class CustomUserSerializer(serializers.ModelSerializer):
    client_profile = ClientProfileSerializer(required=False)
    instructor_profile = InstructorProfileSerializer(required=False)
    lookup_field = 'slug'

    class Meta:
        model = models.CustomUser
        fields = '__all__'

My model:

class OffPeaksUser(auth_models.AbstractBaseUser, auth_models.PermissionsMixin):
    '''Custom user model
    '''
    objects = UserManager()
    # Fields
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)
    slug = models.SlugField(max_length=200, unique=True, null=True)
    profile_image = models.ImageField(blank=True, null=True)
    title = models.CharField(max_length=10, blank=True, null=True)
    biography = models.TextField(blank=True, null=True)
    newsletter = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in api_endpoint.py at get_serializer_fields, then trace how ApiDocumentation in api_docs.py discovers endpoints. Reproduce the /api/v1/ failure with a custom user model using USERNAME_FIELD = 'email' and compare it with serializer field inspection in the shell. Done means the documentation root loads without ImproperlyConfigured.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
documentation
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.