Skip to main content
 首页 » 编程设计

python之Natural Key 导致 Django 测试失败

2024年10月25日37lyj

考虑一个干净的 django 1.7.7 项目,其中包含一个名为 testrunner 的应用。

模型看起来像这样:

class Contact(AbstractBaseUser, PermissionsMixin, models.Model): 
    relation = models.ForeignKey('tests.Relation', related_name='contacts') 
    username = models.CharField(max_length=200, unique=True) 
    first_name = models.CharField(max_length=30, null=True, blank=True) 
    last_name = models.CharField(max_length=30, null=True, blank=True) 
    email = models.EmailField(null=True, blank=True, unique=True) 
 
    is_staff = models.BooleanField('staff status', default=False, 
                                   help_text='Designates whether the user can log into this admin site.') 
    is_active = models.BooleanField('active', default=True, 
                                    help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.') 
 
    USERNAME_FIELD = 'username' 
 
    def get_full_name(self): 
        pass 
 
    def get_short_name(self): 
        pass 
 
    def get_name(self): 
        pass 
 
class Relation(models.Model): 
    name = models.CharField(max_length=200, unique=True) 
    created_by = models.ForeignKey('tests.Contact', null=True, related_name='created_%(class)s') 
    modified_by = models.ForeignKey('tests.Contact', null=True, related_name='modified_%(class)s') 
 
    def natural_key(self): 
        return (self.name,) 

在 settings.py 中,我将 'tests.Contact' 设置为 AUTH_USER_MODEL。

此设置是一个干净的测试,用于复制我在更大环境中遇到的错误。问题是如果没有在创建测试数据库时失败,我就无法运行 django 测试:

manage.py test 
Testing started at 14:39 ... 
Creating test database for alias 'default'... 
CommandError: Can't resolve dependencies for tests.Contact, admin.LogEntry, tests.Relation in serialized app list. 
 
Process finished with exit code 1 
Empty test suite. 

当我从关系模型中删除 def natural_key(self) 时,一切正常。 我们想在我们的固定装置的关系模型上使用 natural_key,但无法让它与 django 测试一起使用。

我做错了什么?

请您参考如下方法:

一个非常简单的解决方案,但我花了一些时间才想出。

tl;博士

  • 动态导入序列化程序。
  • 动态定义natural_keys 方法并分配给模型。

def method_where_serializers_is_being_used(): 
    # import serlializers 
    from django.core import serializers 
     
    # define natural_key method 
    def natural_key(self): 
        return some_unique_id 
 
    DjangoModel.natural_key = natural_key   

这是一种 hack,但它工作正常