Django queryset命令在第二个模型中作为OneToOnefield存在

时间:2014-05-04 17:33:43

标签: django django-models django-views django-queryset

我正在尝试根据两个模型之间的关系构建queryset。以下是它们的外观:

class Foo(models.Model):
    name = models.CharField(max_length=150)
    date = models.DateTimeField(editable=False)
    ...

    class Meta:
        ordering = ['-date']


class Bar(models.Model):
    foo = models.OneToOneField(Foo, related_name='bars')
    from_date = models.DateTimeField(editable=False)

    class Meta:
        ordering = ['from_date']

现在我需要Foo个对象的查询集,但首先我希望在Bar模型中存在对象,使用Bar默认排序,然后使用Foo排序的其余Foo个对象。以下给我一个很好的混乱:

q = Foo.objects.all().order_by('bars','-date').distinct()

同样有趣的是,我在django1.5和django1.6中为上面的查询集获得了不同的顺序。

1 个答案:

答案 0 :(得分:0)

您只需要将Bar对象链接到它们的Foo对象,即:filter。

Foo.objects.filter(bars__isnull=False)

但这只会按照Foo日期的默认顺序排序 要拥有您想要的东西,您需要在此查询集中使用order_by

Foo.objects.filter(bars__isnull=False).order_by('bars', '-date')

我不确定order_by('bars')。它是按特定字段(from_date)还是id?

排序的

我用django 1.6测试过,order_by是在右边的字段(from_date)上完成的,所以django 1.5可能是id上的order_by,而不是特定的字段因此不同的排序?

您可以强制该字段选择是否需要在两个版本上兼容或只是为了可读性。

Foo.objects.filter(bars__isnull=False).order_by('bars__from_date', '-date')

另一点

由于您的关系是OneToOne related_name,因此它不应该有最终的s(条形而不是条形)。这将澄清你的代码,因为django将OneToOne关系与其他关系略有不同 事实上,如果你有一个ForeignKey关系,你将不得不这样做得到一个(或所有)Bar对象:

foo = Foo.objects.get(id=1)
bars = foo.bars.all()

使用OneToOne,您只需要这样做:

foo = Foo.objects.get(id=1)
bar = foo.bar

不同之处在于,OneToOne关系确保Foo对象链接到一个且只有一个Bar对象,具有ForeignKey关系,Foo对象可以将一个或多个Bar对象链接到它。