如何让FactoryBoy不为非托管Django模型生成id属性?
解决方案
1. 修正Django模型定义
你的非托管模型Person未显式指定主键,Django会自动添加默认的id字段,但数据库视图v_person不存在这个列,导致查询报错。需要给personality_id字段添加primary_key=True,让Django不再自动生成id字段:
class Person(models.Model): # 显式指定主键,避免Django自动添加id字段 personality_id = models.IntegerField(db_column="personalityID", primary_key=True) state_id = models.IntegerField(db_column="stateID") first_name = models.CharField(db_column="firstName", max_length=35) last_name = models.CharField(db_column="lastName", max_length=40) middle_name = models.CharField(db_column="middleName", max_length=30) number = models.IntegerField(db_column="studentNumber") active_year = models.IntegerField(db_column="activeYear") birth_date = models.DateField(db_column="BirthDate") start_date = models.DateField(db_column="startDate") end_date = models.DateField(db_column="endDate", null=True) end_year = models.IntegerField(db_column="endYear") gender = models.CharField(db_column="gender", max_length=1) native_lang = models.CharField(db_column="languageAlt", max_length=5) class Meta(object): managed = False db_table = "v_person"
2. 调整FactoryBoy的实例生成策略
如果你的需求只是生成数据实例而非写入数据库,将PersonFactory.create()改为PersonFactory.build(),这样FactoryBoy不会触发数据库的get_or_create操作,也就不会产生查询id列的SQL:
修改RatedPersonalityFactory中的post_generation方法:
@post_generation def person(obj, create, extracted, **kwargs): # 使用build()替代create(),仅生成内存中的模型实例 PersonFactory.build( personality=obj, personality_id=obj.id, state_id=1234, first_name=obj.identity.first_name, last_name=obj.identity.last_name, middle_name=obj.identity.middle_name, birth_date=obj.identity.birth_date, number=obj.student_number, end_year=kwargs["end_year"], )
3. 可选:如果必须写入数据库
若需要将数据写入数据库(非托管模型通常不需要,但如果有特殊需求),确保PersonFactory的Meta配置正确,且模型主键与数据库视图匹配:
class PersonFactory(DjangoModelFactory): class Meta: model = Person database = "alternatives" # 基于显式主键字段进行get_or_create django_get_or_create = ("personality_id",)
内容的提问来源于stack exchange,提问作者UpDawg
相关产品推荐
相关产品推荐

