Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 过滤Django queryset中不存在的GenericForeignKey对象_Python_Django_Django Queryset_Django Generic Views_Django Contenttypes - Fatal编程技术网

Python 过滤Django queryset中不存在的GenericForeignKey对象

Python 过滤Django queryset中不存在的GenericForeignKey对象,python,django,django-queryset,django-generic-views,django-contenttypes,Python,Django,Django Queryset,Django Generic Views,Django Contenttypes,我有一个带有通用外键的简单模型: class Generic(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') 我想筛选此表中具有非空内容对象的所有条目,即筛选出其内容对象不再存在的通用的所

我有一个带有通用外键的简单模型:

class Generic(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
我想筛选此表中具有非空
内容对象的所有条目,即筛选出其内容对象不再存在的
通用
的所有实例

Generic.objects.filter(~Q(content_object=None))
这不起作用,出现以下例外情况:

django.core.exceptions.FieldError:字段“内容\对象”不存在 生成自动反向关系,因此无法使用 用于反向查询。如果它是通用的外键,请考虑添加 一般关系

generirelation
添加到引用的内容类型模型中没有任何区别

任何关于如何实现这一点的帮助都将不胜感激,非常感谢


编辑:我意识到我可以级联删除,但在我的情况下这不是一个选项(我希望保留数据)。

如果你想过滤掉一些记录,通常最好使用以下方法:

但是请注意,您的模型现在不允许空的
content\u object
字段。要更改此行为,请使用
object\u id
content\u type
字段的
null=True
参数

更新 好的,因为问题已经从过滤空记录转移到在没有RDBMS自身帮助的情况下确定损坏的RDBMS引用,所以我建议一种(相当缓慢且内存不足的)解决方法:

broken_items = []
for ct in ContentType.objects.all():        
    broken_items.extend(
        Generic.objects
        .filter(content_type=ct)
        .exclude(object_id__in=ct.model_class().objects.all())
        .values_list('pk', flat=True))

这将作为一次性脚本工作,但不是一个健壮的解决方案。如果你绝对想保留数据,我能想到的唯一快速方法是在你的
通用
模型中设置
is\u deleted
布尔标志,并将其设置为
(post | pre)\u delete
信号。

另一个人评论了同样的解决方案,然后删除了它,因为它不起作用,除非你的是无效的,因为这将检查
对象\u id
字段是否为空,而不是该id引用的相关对象。无论哪种方式,如果你修复了它,它仍然会给出与原始问题中发布的相同的异常。过滤或排除在这里没有区别。FWIW checking
=None
isnull=True
.Ben相同,但是“non-null”
content\u object
意味着什么?它只是数据库中两个实际字段的(足够薄)包装器。如果您想排除没有引用任何其他模型的
泛型,我上面给出的查询就是有效的查询。或者请细化您对回答中的“空对象”。嗨,亚历克斯,我已经澄清了这个问题。非空表示可以使用
object\u id
定义的id从
content\u type\u id
定义的表中检索的实际对象。例如,如果你和一个已经被删除的对象有一个泛型关系。好的,现在我明白了。看看我对它的最新想法。在第二个版本中,排除不是应该在
object\u id
而不是
pk
.exclude(object\u id\u In=ct.model\u class().objects.all())
?(因为
pk
将引用
Generic
自己的id,而不是要检查的相关型号的id。)
broken_items = []
for ct in ContentType.objects.all():        
    broken_items.extend(
        Generic.objects
        .filter(content_type=ct)
        .exclude(object_id__in=ct.model_class().objects.all())
        .values_list('pk', flat=True))