【问题标题】:Django - Finding all related OneToOneField objects through the foreign objectDjango - 通过外来对象查找所有相关的 OneToOneField 对象
【发布时间】:2021-10-04 13:36:23
【问题描述】:

对不起,如果标题不清楚,这就是我想要完成的:

class Document(models.Model):
    processed = models.BooleanField(default=False)

class ParentClass(models.Model)
    document = models.OneToOneField(Document, on_delete=models.SET_NULL, null=True)

    class Meta:
        abstract = True

    def do_something():
        raise NotImplementedError()

class SubclassOne(ParentClass):
    # Some fields.
    def do_something(self):
        # Something specific to this subclass

class SubclassTwo(ParentClass):
    # Some other fields.
    def do_something(self):
        # Something specific to this subclass

我的第一个想法是尝试通过ParentClass查询

ParentClass.objects.filter(document__processed=False)

但这不起作用,因为父类是abstract

现在我尝试通过 Document 对象

Document.objects.filter(processed=False)

但似乎没有办法通过每个Document 查找相关对象。我不确定这是一个好的解决方案,因为ParentClassDocument 紧密耦合,它不需要知道ParentClass 的实现。

【问题讨论】:

    标签: django django-models orm one-to-one


    【解决方案1】:

    您可以找到所有反向相关的字段名称,并且可以循环如下:

    documents = Document.objects.filter(processed=False)
    reverse_related_fields = Document._meta.get_fields()
    
    for document in documents:
        for reverse_related_field in reverse_related_fields:
            if reverse_related_field.one_to_one:
                attr = getattr(document, f"{reverse_related_field.name}_set")
                try:
                    attr.get().do_something
                except Exception:
                    pass
    

    【讨论】:

    • 是的,这将为我提供SubclassOne 实例的结果,但我需要一种方法来获得包含SubclassTwo(最终是SubclassThreeSubclassFour 等)的结果。
    • 哦,明白了!编辑我的答案。您可以通过反向查找来做到这一点。
    【解决方案2】:
    ParentClass.objects.filter(document__processed=False)
    

    这将返回所有已处理的文档设置为False

    【讨论】:

    • 我试过这个(我应该将它包含在我的示例代码中),但我得到了一个 AttributeError: type object 'ParentClass' has no attribute 'objects' 。我猜那是因为ParentClass 被定义为abstract
    • 哦,你是对的,没有注意到这一点。仅当您删除抽象类时才能使用此解决方案,但我想这对您没有帮助,我的错
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    • 2017-08-06
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    相关资源
    最近更新 更多