首页 > 解决方案 > 获取 Django 中的当前用户不在测试中工作

问题描述

我的 Django 应用程序中有几个视图执行和操作并记录谁在数据库中执行了操作,例如:

def my_view(request):
    # do some stuff here first
    current_user = MyCustomUserObject.objects.filter(django_user_id=request.user.id).first()
    model_i_did_something_to_above.last_modified_by = current_user
    model.save()

如果我运行服务器并通过邮递员调用它,这实际上工作正常。但是,当我进行单元测试时:

from datetime import datetime

class MyTests(TestCase):

    def setUp(self):
        now = datetime.utcnow()
        django_user = User.objects.create_user(username='myusername',
                                           email='test@test.com',
                                           password='abcd')
        
        self.user = MyCustomUserObject(user_name='myusername', email_address='test@test.com', created_datetime=now,
                    last_modified_datetime=now, is_admin=True, django_user=django_user)
        self.user.save()
        self.tokens = json.loads(self.client.post(reverse('authenticate'),
                                                  data={'username': 'myusername',
                                                        'password': 'abcd'},
                                                  content_type='application/json').content)

    def test_stuff(self):
        self.client.delete(reverse('nameoftheurl'),
                               {data: 'stuff'},
                               content_type='application/json',
                               **{'HTTP_AUTHORIZATION': self.tokens['access']})

它到达视图,它说 request.user.id 是 None。为什么会这样?有没有解决的办法?

编辑

身份验证视图如下所示:

from rest_framework_simplejwt.views import TokenObtainPairView

urlpatterns = [
    path('authenticate/', TokenObtainPairView.as_view(), name='authenticate'),
    ]

我还更新了上面的测试示例以显示用户是如何创建的。

标签: pythondjango

解决方案


问题似乎是因为您的授权标头在您的test_stuff测试用例中缺少授权类型。

它应该是:

headers={'Authorization': f"Bearer {self.tokens['access']}"}

所以:

    def test_stuff(self):
        self.client.delete(reverse('nameoftheurl'),
                               {data: 'stuff'},
                               content_type='application/json',
                               **{'HTTP_AUTHORIZATION': f"Bearer {self.tokens['access']}")
                                                       #  ^^^ Add this

推荐阅读