python - 如何在 Django 管理页面的单元测试中对用户进行身份验证?
问题描述
我正在尝试调整来自Testing custom admin actions in django的答案,但我遇到了一些意外行为。我创建了一个简化的 Django 应用程序myapp
,它有一个Worker
和Invoice
模型:
class Worker(models.Model):
name = models.CharField(max_length=255)
class Invoice(models.Model):
UNPAID = 0
PAID = 1
worker = models.ForeignKey(
'Worker', on_delete=models.CASCADE)
amount = models.DecimalField(
max_digits=10, decimal_places=2)
amount_paid = models.DecimalField(
max_digits=10, decimal_places=2, default=Decimal('0.00'))
status = models.IntegerField(
choices=[(UNPAID, 'Unpaid'), (PAID, 'Paid')], default=0)
我创建了一个名为的自定义管理操作mark_as_paid
,它将所选发票的状态更改为Invoice.PAID
in admin.py
:
from django.contrib import admin
from django.db.models import F
from .models import Invoice
@admin.register(Invoice)
class InvoiceAdmin(admin.ModelAdmin):
list_display = ('worker', 'status', 'amount', 'amount_paid')
actions = ['mark_as_paid']
def mark_as_paid(self, request, queryset):
queryset.update(amount_paid=F('amount'))
我正在尝试这样测试:
from decimal import Decimal
from django.contrib import admin
from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse
from myapp.models import Invoice, Worker
class InvoiceAdminTests(TestCase):
def setUp(self):
self.user = User.objects.create_user(
username='foobar',
email='foo@bar.com',
password='barbaz',
is_superuser=True)
self.client.force_login(user=self.user)
def test_mark_as_paid(self):
worker = Worker.objects.create(name="John Doe")
invoice = Invoice.objects.create(
worker=worker, amount=Decimal('100.00'))
response = self.client.post(
reverse('admin:myapp_invoice_changelist'),
data={
'action': 'mark_as_paid',
admin.ACTION_CHECKBOX_NAME: [invoice.id]})
import ipdb; ipdb.set_trace()
invoice.refresh_from_db()
self.assertEqual(invoice.amount_paid, Decimal('100.00'))
我在测试中设置了调试器跟踪,但最终我希望它通过。但是,目前它正在失败,因为invoice.amount_paid
仍然是Decimal('0.00')
.
奇怪的是,响应的状态码为 302(不是 200)和空内容:
ipdb> response.status_code
302
ipdb> response.content
b''
我还在该mark_as_paid()
方法中设置了一个跟踪并且它没有被命中,所以我怀疑我模拟用户身份验证的方式有问题,因为如果我创建一个超级用户python manage.py createsuperuser
并手动测试它,一切正常正如预期的那样。
知道这种方法有什么问题吗?
解决方案
更仔细地查看在 django中测试自定义管理操作的示例,结果发现我需要使用该create_superuser()
方法而不是create_user()
with is_superuser=True
。测试通过以下修改setUp()
方法:
class InvoiceAdminTests(TestCase):
def setUp(self):
self.user = User.objects.create_superuser(
username='foobar',
email='foo@bar.com',
password='barbaz')
self.client.force_login(user=self.user)
推荐阅读
- reactjs - 同行 react-dom@15.6.2 想要 react@^15.6.2
- ios - 从 HealthKit 中查询心率值会导致应用崩溃
- redis - 使用 lua 的 redis 列表上的数值函数
- node.js - Array.every 函数的闭包是异步的还是同步的
- c - mktime() 返回大量秒数
- powershell - 在管道中显示两种方法
- ruby - 如何在 Nokogiri 中提取部分文本
- php - exec() 如何工作 - PHP 和 Wordpress
- node.js - nodejs smtp-server 电子邮件已发送但未收到
- angular - Angular CLI 版本 7.3.3 与 Typescript 版本 3.3.3333 不兼容