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

Django删除C模型实例触发FieldError:无法解析content_type字段

Django 删除继承模型时 FieldError 问题解决

问题场景

定义了如下Django模型类,执行C实例的delete()方法时抛出字段解析错误:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.utils.timezone import now

class A(models.Model):
    created_time = models.DateTimeField(default=now, null=True, blank=True)
    t = GenericRelation(T, object_id_field='object_id', content_type_field='content_type', related_query_name='a')

class B(A):
    state_path = models.CharField(max_length=256, blank=True, verbose_name="State Path")
    f = GenericRelation(F, content_type_field='content_type', object_id_field='object_id', related_query_name='b')

class C(B):
    choice = models.BooleanField(default=False, verbose_name="Enabled")
    
class T(models.Model):
    created_time = models.DateTimeField(auto_now_add=True, verbose_name="Created Time")
    content_type = models.ForeignKey(ContentType, null=True, blank=True, on_delete=models.DO_NOTHING)
    object_id = models.PositiveIntegerField(null=True, blank=True)
    a = GenericForeignKey('content_type', 'object_id')

class E(models.Model):
    username = models.CharField(max_length=128, verbose_name="Username")
    key = models.TextField(blank=True, verbose_name="Key")

class F(E):
      content_type = models.OneToOneField(ContentType, on_delete=models.CASCADE)
      object_id = models.PositiveIntegerField()
      b = GenericForeignKey('content_type', 'object_id')

# 执行删除操作时出错
c = C.objects.get(pk=c_id)
c.delete()

错误信息

django.core.exceptions.FieldError: Cannot resolve keyword 'content_type' into field. Choices are: id

原因分析

删除C实例时,Django会自动清理其关联的GenericRelation对象(即B类中定义的f关联)。由于F采用多表继承自E,Django在处理反向关联查询时,错误地使用了父类E的模型进行查询,而E中并没有content_type字段,因此抛出字段解析错误。

解决方案

方案1:将父类E改为抽象基类

把E设置为抽象基类,这样F会直接继承E的字段到自身数据表中,不会生成单独的E表,查询时就能正确找到content_type字段:

class E(models.Model):
    username = models.CharField(max_length=128, verbose_name="Username")
    key = models.TextField(blank=True, verbose_name="Key")

    class Meta:
        abstract = True  # 标记为抽象基类

class F(E):
      content_type = models.OneToOneField(ContentType, on_delete=models.CASCADE)
      object_id = models.PositiveIntegerField()
      b = GenericForeignKey('content_type', 'object_id')

方案2:调整GenericRelation参数

如果保留多表继承结构,可在B类的GenericRelation中添加for_concrete_model=False参数,确保查询指向子类F而非父类E:

class B(A):
    state_path = models.CharField(max_length=256, blank=True, verbose_name="State Path")
    f = GenericRelation(
        F,
        content_type_field='content_type',
        object_id_field='object_id',
        related_query_name='b',
        for_concrete_model=False  # 指定关联非具体模型
    )

两种方案任选其一后,重新执行删除操作即可正常运行。

内容的提问来源于stack exchange,提问作者Jepsenwan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:37:41