Skip to content

Django REST Framework's request object breaks clear_participant_cache signal handler #158

@Kobold

Description

@Kobold

I intend to put together a PR to address this issue. Just wanted to document it in case anybody else runs into it.

We recently started doing logins via a DRF api_view endpoint on our site and began getting AttributeErrors from django-experiments, specifically the clear_participant_cache handler.

This is occurs because the handler looks like:

def clear_participant_cache(request):
    if hasattr(request, '_experiments_user'):
        del request._experiments_user

DRF uses its own request object where it stores a copy of the original Django request at request._request, and delegates to the original request with an implementation of __getattribute__.

So the hasattr succeeds (and finds request._request._experiments_user) but the del is not delegated to the original Django request object and so fails with an AttributeError.

This is probably "truly" a bug in DRF, but django-experiments should deal with it in any case.

Full example stack trace:

Traceback (most recent call last):
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
                  response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
          return view_func(*args, **kwargs)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
              return self.dispatch(request, *args, **kwargs)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/rest_framework/views.py", line 474, in dispatch
              response = self.handle_exception(exc)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/rest_framework/views.py", line 434, in handle_exception
              self.raise_uncaught_exception(exc)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/rest_framework/views.py", line 471, in dispatch
              response = handler(request, *args, **kwargs)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/rest_framework/decorators.py", line 52, in handler
              return func(*args, **kwargs)
  File "myapp/views.py", line 642, in signup_verify_success
          get_adapter().login(request, user)
  File "myapp/adapters.py", line 183, in login
              super(MyAppAllauthAdapter, self).login(request, user)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/allauth/account/adapter.py", line 309, in login
          django_login(request, user)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 130, in login
      user_logged_in.send(sender=user.__class__, request=request, user=user)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 191, in send
              response = receiver(signal=self, sender=sender, **named)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/experiments/signal_handlers.py", line 9, in transfer_enrollments_to_user
      clear_participant_cache(request)
  File "/mysite_virtualenv/local/lib/python2.7/site-packages/experiments/utils.py", line 35, in clear_participant_cache
          del request._experiments_user
AttributeError _experiments_user

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions