2

我正在使用 Django 3.2b1 和 pytest 6.2.2。

我正在尝试使用 pytest 编写测试,以确保管理员能够使用该delete_selected操作删除对象。我的测试如下所示:

def test_delete_mymodel_action(admin_client):
    objs_to_delete = [
        MyModel.objects.create(),
        MyModel.objects.create(),
    ]
    MyModel.objects.create() # Don't delete this obj

    data = {
        "action": "delete_selected",
        "_selected_action": [str(f.pk) for f in objs_to_delete],
        "post": "yes",  # Skip the confirmation page
    }
    change_url = reverse("admin:myapp_mymodel_changelist")
    admin_client.post(change_url, data)

    assert MyModel.objects.count() == 1

代码工作并以 302 重定向结束,返回到更改列表,但对象不会被删除。回应是:

test_delete_mymodel_action - assert 3 == 1

我正在测试的原因是某些代码可能会导致delete_selected操作失败。例如,如果您get_queryset()在 中覆盖ModelAdmin并返回使用的查询集distinct(),则delete_selected操作将失败。

这是 Django Admin 中删除确认页面的代码:

<form method="post">
    <input type="hidden" name="csrfmiddlewaretoken" value="VCR7vjVYcb2xuMdPUknotrealViwj92wgZrT21k6RbqGxXNlQnCORU1Fp6NzKhn64">
    <div>
        <input type="hidden" name="_selected_action" value="31418">
        <input type="hidden" name="_selected_action" value="31412">
        <input type="hidden" name="action" value="delete_selected">
        <input type="hidden" name="post" value="yes">
        <input type="submit" value="Yes, I’m sure">
        <a href="#" class="button cancel-link">No, take me back</a>
    </div>
</form>

一些有用的参考资料:

  1. Django 的 delete_selected() 方法。
  2. 在 django SO Answer 中测试自定义管理操作
4

1 回答 1

0

我只是遇到了同样的问题。我注意到我用错误的用户登录。

我的思考过程:

  • 302不表示有什么问题,响应中也没有内容(b''
  • 我添加follow=Trueself.client.post. 响应是200并且没有对象,所以我认为它工作正常,但断言失败
  • 我在delete_selectedofdjango.contrib.admin.actionsn = queryset.count()was中设置了断点0
  • 如果后面没有列出但没有什么可删除的(n = 0),我们看看之前有没有要删除的东西。
    response = self.client.get(reverse("admin:myapp_mymodel_changelist"))
    self.assertContains(response, obj.id)

不!

所以你的测试的问题是这些对象不能被删除,因为它们不能被检索,可能是由于一些过滤。

注意,如果没有找到对象,Django admin 不会引发 404。

于 2021-05-07T13:13:01.303 回答