如何为测试初始化自定义模型字段VaultField?
问题
我定义了一个继承自CharField的自定义模型字段VaultField,用来在Vault中存储值,使用方式如下:
class MyClass: secret = VaultField(max_length=200, blank=True)
这个字段内部用到了self.model.__name__。我想通过初始化字段并调用它的方法(比如from_db_value、to_python等)来做单元测试:
field = VaultField(blank=True) field.to_python()
但运行时因为字段依赖self.model报错:
AttributeError: 'VaultField' object has no attribute 'model'
我试过直接在初始化时传model参数,但没用:
VaultField(max_length=200, blank=True, model=MyModel)
解决方案
方法1:手动绑定model属性
先定义一个测试用的模型类,直接给字段对象赋值model属性即可:
# 定义简单的测试类(非Django模型也可) class TestModel: pass field = VaultField(blank=True) field.model = TestModel # 此时可正常调用字段方法 field.to_python("test_value")
如果是Django环境,也可以用Django模型类(无需创建数据库表):
from django.db import models class TestModel(models.Model): class Meta: managed = False field = VaultField(blank=True) field.model = TestModel
方法2:从测试模型中获取字段
Django会在模型类创建时自动给字段绑定model属性,所以可以先定义包含该字段的测试模型,再从模型中获取字段:
from django.db import models class TestModel(models.Model): secret = VaultField(max_length=200, blank=True) class Meta: managed = False # 从模型元数据中获取已绑定model的字段 field = TestModel._meta.get_field('secret') field.to_python("test_value")
方法3:修改VaultField实现,兼容无model场景
为了让字段在测试时更友好,可以修改字段代码,处理model未绑定的情况:
class VaultField(models.CharField): def to_python(self, value): # 当model未绑定时,使用默认名称替代 model_name = self.model.__name__ if hasattr(self, 'model') else 'TestModel' # 原有业务逻辑... return value # 其他用到self.model的方法都做类似兼容处理
内容的提问来源于stack exchange,提问作者himmip
相关产品推荐
相关产品推荐

