Django 测试失败,通用 CreateView 中 get_inital 中的 request.user

发布于 2024-12-29 05:40:03 字数 1181 浏览 1 评论 0原文

我有一个像这样的通用视图:

class SaveView(CreateView):

    def get_initial(self):
        # Get the initial dictionary from the superclass method
        initial = super(SaveView, self).get_initial()
        # Copy the dictionary so we don't accidentally change a mutable dict
        initial = initial.copy()
        initial['user'] = self.request.user
        return initial

该视图具有 login_required 装饰器,因此 self.request.user 始终有效。

当我使用浏览器访问该页面时,一切正常,但我的测试失败了。我有以下测试设置:

from django.test import TestCase, client

class MyTest(TestCase):
    def setUp(self):
        self.client = client.Client()
    def test1(self):
        self.assertTrue(self.client.login(username='user1',password='password1'))
        data = {'name':'test 1'}
        response = self.client.post('/app/save/', data)
        self.assertEqual(response.status_code, 302)

'/app/save/' 是调用该视图的 url(它在浏览器上完美运行) 我的模型有 2 个必填字段“名称”和“用户”,因此这应该会重定向到创建的对象页面,因为我已经通过数据传递了名称,并且应该从 get_initial 方法获取用户。

事实上,这就是“现实生活”(即浏览器)中发生的情况。

我可以使此测试成功通过数据字典中的“用户”的唯一方法。

这是 django.test 模块中的错误还是这是预期的行为以及为什么?

提前致谢

I have a generic view like this:

class SaveView(CreateView):

    def get_initial(self):
        # Get the initial dictionary from the superclass method
        initial = super(SaveView, self).get_initial()
        # Copy the dictionary so we don't accidentally change a mutable dict
        initial = initial.copy()
        initial['user'] = self.request.user
        return initial

This view has the login_required decorator, so self.request.user is always valid.

When I'm accessing the page with the browser, everything is working fine, but my tests are failing. I have the following test setup:

from django.test import TestCase, client

class MyTest(TestCase):
    def setUp(self):
        self.client = client.Client()
    def test1(self):
        self.assertTrue(self.client.login(username='user1',password='password1'))
        data = {'name':'test 1'}
        response = self.client.post('/app/save/', data)
        self.assertEqual(response.status_code, 302)

'/app/save/' is the url that calls that view (it's working perfectly on the browser
My model has 2 mandatory fields "name" and "user", so this should issue a redirect to the created object page, since I have passed the name through data and the user should be got from get_initial method.

Indeed this is what happens in the "real life", i.e. browser.

The only way I could make this test pass successfully passing the 'user' in the data dictionary.

Is this a bug in django.test module or this is the expected behavior and why?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心欲静而疯不止 2025-01-05 05:40:03

这是预期的行为。来自 Django 文档中关于初始数据的信息:

初始参数允许您指定在未绑定表单中呈现此字段时要使用的初始值。

当您在测试中发布数据时,您使用的是绑定表单,因此不使用初始数据。该表单无效,因为缺少必需的 user 字段,因此会返回显示表单错误的 200 响应。这与您清除浏览器中的用户字段并提交表单时发生的情况相同。

您需要将用户包含在您的 post 数据中,然后测试就会通过。

This is expected behaviour. From the Django docs on initial data:

The initial argument lets you specify the initial value to use when rendering this Field in an unbound Form.

When you post data in your test, you are using a bound form, so initial data is not used. The form is invalid because the required user field is missing, so a 200 response is returned that displays the form errors. This is same as what would happen if you cleared the user field in your browser, and submitted the form.

You need to include the user in your post data, then, the test will pass.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文