Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Kobold opened this issue Dec 25, 2016 · 0 comments

Comments

@Kobold
Copy link
Contributor

Kobold commented Dec 25, 2016

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant