You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:16:59