【问题标题】:Testing with a custom user model as a ForeignKey in Django 1.5在 Django 1.5 中使用自定义用户模型作为 ForeignKey 进行测试
【发布时间】:2013-02-28 11:35:42
【问题描述】:

我正在使用 Django 1.5,并且正在尝试使应用程序与任何自定义用户模型一起工作。我已将应用程序更改为在任何地方使用get_user_model,并且应用程序本身目前没有出现任何问题。

问题是我也希望能够测试应用程序,但我找不到使ForeignKey 模型字段使用自定义用户模型正确测试的方法。当我运行下面附加的测试用例时,我收到了这个错误:

ValueError: Cannot assign "<NewCustomUser: alice@bob.net>": "ModelWithForeign.user" must be a "User" instance.

这是我用于测试的文件:

from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.tests.custom_user import CustomUser, CustomUserManager
from django.db import models
from django.test import TestCase
from django.test.utils import override_settings

class NewCustomUser(CustomUser):
    objects = CustomUserManager()
    class Meta:
        app_label = 'myapp'

class ModelWithForeign(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

@override_settings(
    AUTH_USER_MODEL = 'myapp.NewCustomUser'
)   
class MyTest(TestCase):
    user_info = {
        'email': 'alice@bob.net',
        'date_of_birth': '2013-03-12',
        'password': 'password1'
    }   

    def test_failing(self):
        u = get_user_model()(**self.user_info)
        m = ModelWithForeign(user=u)
        m.save()

我在ForeignKey 参数列表中引用用户模型,如here 所述,但使用get_user_model 并没有改变任何东西,因为在设置更改发生之前评估user 属性。当我使用自定义用户模型时,有没有办法让这个 ForeignKey 与测试相得益彰?

【问题讨论】:

    标签: python django django-testing django-1.5


    【解决方案1】:

    我也在 Django 邮件列表中询问过这个问题,但似乎至少目前无法更改 settings.AUTH_USER_MODEL 并让它与 ForeignKey 很好地配合使用。

    到目前为止,为了测试我的应用,我从this answer 创建了一个runtests.py 文件:

    import os, sys
    from django.conf import settings
    
    if len(sys.argv) >= 2:
        user_model = sys.argv[1]
    else:
        user_model = 'auth.User'
    
    settings.configure(
        ...
        AUTH_USER_MODEL=user_model,
        ...
    )
    
    ...
    

    并添加了一个 bash 脚本以使用不同的用户模型实际运行测试:

    for i in "auth.User" "myapp.NewCustomUser"; do
        echo "Running with AUTH_USER_MODEL=$i"
        python runtests.py $i
        if [ $? -ne 0 ]; then
            break
        fi
    done
    

    最后一点是使用函数来实际检索正确的用户模型信息,而不是仅仅使用“静态”变量:

    def get_user_info():
        if settings.AUTH_USER_MODEL == 'auth.User':
            return {default user info}
        if settings.AUTH_USER_MODEL == 'myapp.NewCustomUser':
            return {my custom user info}
        raise NotImplementedError
    

    我并没有声称这是该问题的正确答案,但到目前为止......它有效。

    【讨论】:

    • 这不是与它是一个站点范围的设置有关,而不是一个特定于应用程序的设置吗?您的解决方案似乎很有意义!
    • @benjaoming 实际上是因为模式没有在测试之间重建(实际上不应该),这使得可交换属性在这种情况下无用,因为它定义了实际存在的表。您几乎可以交换任何其他内容,docs 显示了一些可以覆盖的站点范围设置的示例。
    猜你喜欢
    • 2013-03-21
    • 2013-02-13
    • 2014-04-05
    • 1970-01-01
    • 2013-12-13
    • 2013-06-01
    • 2013-04-20
    • 2013-02-24
    • 2013-04-05
    相关资源
    最近更新 更多