【问题标题】:How can I follow a Django reverse-foreign-key and then another reverse-foreign-key?如何遵循 Django 反向外键,然后再遵循另一个反向外键?
【发布时间】:2015-10-01 03:51:08
【问题描述】:

假设我有 3 个 Django 模型:

mymodela/models.py:

class MyModelA(models.Model):
    my_int = models.IntegerField()
    created_ts = models.DateTimeField()

mymodelb/models.py:

from mymodela.models import mymodela
class MyModelB(models.Model):
    my_int = models.IntegerField()
    my_a = models.ForeignKey(MyModelA, related_name="MyModelB_a")
    created_ts = models.DateTimeField()

mymodelc/models.py:

from mymodelb.models import MyModelB
class MyModelC(models.Model):
    my_int = models.IntegerField()
    my_b = models.ForeignKey(MyModelB, related_name="MyModelC_b")
    created_ts = models.DateTimeField()

我有一个名为aMyModelA 实例。我想计算这个查询集:

MyModelC.objects.filter(my_b__my_a=a).latest("created_ts")

但是,我需要从a 的方法中计算这个查询集。而且由于MyModelA 不导入MyModelC,我不能直接这样做。我需要遵循反向链接。但是我怎样才能按照反向链接两次来获得我需要的东西呢?

【问题讨论】:

  • 为什么不能在MyModelA 方法中导入MyModelC 并运行上面已经指定的查询?
  • MyModelA 中导入MyModelC 会导致循环依赖。对吗?
  • 不 - 让我在下面发布一个示例。

标签: python django django-models django-orm


【解决方案1】:

在您的mymodela/models.py 中(顺便说一句,我不确定您为什么将所有模型分成这样的单独目录 - 除非这是故意的,否则您可以考虑将它们全部放在应用程序的 models.py 文件中):

class MyModelA(models.Model):
    my_int = models.IntegerField()
    created_ts = models.DateTimeField()

    # A method that will fetch the most recent related MyModelC 
    def get_latest_c(self):
        from mymodelc.models import MyModelC
        return MyModelC.objects.filter(my_b__my_a=self).latest("created_ts")

现在,当您有一些名为 aMyModelA 实例时,您可以调用 a.get_latest_c() 以获取最新的相关 MyModelC 对象。

【讨论】:

  • 怀疑,添加from mymodelc.models import MyModelC给了我一个导入错误:gist.github.com/saqib-zmi/f8319ab6c474edbe6bc4
  • 这完全是一个不同的问题 - 无法从您的 mymodelb/models.py 导入 MyModelA。如果您发布您正在使用的完整代码,那么追踪错误会更容易。
  • 没有。这不是一个不同的问题。没有我插入的那一行,代码运行良好。当我插入那行时,出现了这个错误。这是有道理的:mymodelb/models.py 不能再导入 MyModelA,因为 myModelA 现在导入 MyModelC,而 MyModelC 又导入 MyModelB,而 MyModelB 又导入 MyModelA,并且永远如此。这是我的实际代码。请随意使用它:drive.google.com/file/d/0B1UFylbhbG2eWDd3NEdPQkU2OFU/…
  • 所以,在 get_latest_c 方法中进行导入。
  • 我看不出你将如何向上移动相关名称,因为当你这样做时,你会得到一个RelatedManager(即,可能有多个相关对象,这是一对多的关系) 并且您必须对其进行迭代,然后才能进入下一个级别。您可以做的是将get_latest_c 方法移出模型并移入(取决于您如何使用它)模板标签。这样可以避免导入问题。
猜你喜欢
  • 2012-10-15
  • 1970-01-01
  • 2016-03-18
  • 2019-12-01
  • 2011-11-25
  • 1970-01-01
  • 2010-11-16
  • 2017-08-26
  • 2013-02-24
相关资源
最近更新 更多