问题
I just moved from Django 1.3.1 to Django 1.4. Right after doing so, a real big number of my tests started to raise these errors:
Traceback (most recent call last):
File "/Volumes/Data/ADay/Website/Backend/(trunk)/project/tests/templatetags.py", line 406, in setUp
self.context = template.RequestContext(self.request)
File "/Library/Python/2.6/site-packages/django/template/context.py", line 176, in __init__
self.update(processor(request))
File "/Volumes/Data/ADay/Website/Backend/(trunk)/project/social_auth/context_processors.py", line 21, in social_auth_by_type_backends
data = backends_data(request.user)
AttributeError: 'WSGIRequest' object has no attribute 'user'
All those errors refer to django-social-auth context processors, which tries to get request.user to build the request context:
def social_auth_by_type_backends(request):
"""Load Social Auth current user data to context.
Will add a output from backends_data to context under social_auth key where
each entry will be grouped by backend type (openid, oauth, oauth2).
"""
data = backends_data(request.user)
data['backends'] = group_backend_by_type(data['backends'])
data['not_associated'] = group_backend_by_type(data['not_associated'])
data['associated'] = group_backend_by_type(data['associated'],
key=lambda assoc: assoc.provider)
return {'social_auth': data}
Doesn't Django pass the request to the functions while building the request context? I don't think that's it, somebody of the social-auth team would probably have found such an issue by now.
edit:
I first thought it would be some issue with a deprecated context_processor, but i checked and they should all be up to date:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.messages.context_processors.messages',
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
'django.core.context_processors.request',
'pages.context_processors.media',
'social_auth.context_processors.social_auth_by_type_backends',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
edit2:
Ok, as the site continues to work, this probably is a problem with my test code. Here it is:
def setUp(self):
self.factory = RequestFactory()
# create an initial request including session data
self.response = self.client.get('/')
self.request = self.factory.get("/") #any valid url will do, i just need a request
self.request.session = self.client.session
self.context = template.RequestContext(self.request)
The last line is then provoking the error. As it is in the setUp() function of my TestCase, it starts to raise that exceptions all over my tests. Why is this not working in Django 1.4 anymore?
回答1:
In case somebody finds this: requests created with the RequestFactory appear not to return a request.user when using RequestContext(request) on them, even when "django.contrib.auth.context_processors.auth" is installed. But passing a user to the request yourself before using RequestContext(request) works fine:
class SampleTestCase(TestCase):
fixtures = ['user_fixture.json']
def test_only_a_sample(self):
request.user = User.objects.get(pk=1)
self.context = RequestContext(request)
# some tests here
This is the code that finally worked for me.
Edit: request can be used via,
from django.test.client import RequestFactory
# code suppressed
def setUp(self):
self.factory = RequestFactory()
and used in
def test_only_a_sample(self):
request = self.factory.get('/') # or any other methods
request.user = User.objects.get(pk=1)
# code follows
回答2:
I needed an authenticated user for testing a privileged view. I needed to get context back in the response. RequestFactory works but it gets an HttpReponse which does not include context.
This is what I did and it worked.
class MyTestCase(TestCase):
def setUp(self):
self.client.login(username='user@myorg.com', password='Secret')
def test_create_event(self):
print("Testing create...")
response = self.client.post('/event/new_event/', form_data_dict)
self.assertEqual(response.status_code, 200)
event_id = response.context['event'].event_id
来源:https://stackoverflow.com/questions/10094727/how-to-access-request-user-while-testing