Skip to content

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

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions