Django GenericForeignKey工厂类报错:GoogleCreative无content_type属性
解决Django Factory创建带GenericForeignKey模型实例的AttributeError问题
问题原因
GoogleCreative实例本身并没有content_type属性,你尝试通过factory.SelfAttribute('creative.content_type')获取该属性自然会抛出AttributeError。正确的做法是通过Django的ContentType.objects.get_for_model()方法,根据传入的creative实例动态获取对应的ContentType对象。
修正后的工厂类代码
首先确保导入ContentType:
from django.contrib.contenttypes.models import ContentType import factory from factory.django import DjangoModelFactory from .models import GoogleCreative, Tag, CreativeTag from django.utils.text import slugify
然后修改CreativeTagFactory:
class CreativeTagFactory(DjangoModelFactory): class Meta: model = CreativeTag exclude = ['creative'] # 必须保留,因为creative是GenericForeignKey,不是数据库字段 class Params: name = factory.Sequence(lambda n: f'tag {n}') tag = factory.SubFactory(TagFactory, name=factory.SelfAttribute('..name')) creative_id = factory.SelfAttribute('creative.id') # 用LazyAttribute动态获取ContentType creative_content_type = factory.LazyAttribute(lambda obj: ContentType.objects.get_for_model(obj.creative))
测试代码验证
你的测试代码不需要修改,保持原样即可:
@pytest.mark.django_db def test_tags_removed(google_creative_factory, creative_tag_factory, user): creative = google_creative_factory() creative_tag_factory(creative=creative, name='Big Fish')
额外说明
- 保留
exclude=['creative']是因为CreativeTag模型中的creative是GenericForeignKey,它不是数据库中实际存在的字段,Django Factory会尝试将所有未排除的字段写入数据库,所以必须排除它避免报错。 LazyAttribute会在工厂创建实例时,根据传入的creative参数动态计算creative_content_type的值,确保获取到正确的ContentType对象。
内容的提问来源于stack exchange,提问作者Jekson
相关产品推荐
相关产品推荐

