Django distinct和order_by,annotate不起作用

时间:2012-10-19 04:13:14

标签: django django-models

我有两张桌子说

class A(models.Model):
    A_version = models.DecimalField(max_digits=4, decimal_places=0)
    A_name = models.CharField(max_length=32, blank=True)
    A_type    = models.CharField(max_length=32, blank=True)
    unique_together(A_version,A_name)

class B(models.Model):
    B_version = models.ForeignKey(A)
    B_name    = models.ForeignKey(A)
    last_reported_time= models.DecimalField(max_digits=4, decimal_places=0)
    unique_together(B_version,B_name)

obj = B.objects.filter(B_name__A_type="Vendor").
        values('B_name','B_version').annotate(Max('last_reported_time')).
        order_by('B_name','B.B_version')

last_reported不是唯一的。

现在我有两个问题。

  1. 当我使用distinct代替annotate时,我无法获得不同的值。所以我按照某些人的建议使用了annotate。我仍然得到非独特的价值观。如何获得不同的值?

  2. 如果我查看上述查询的原始sql查询,则会将其翻译为order_by(B.B_name and A.B_version)。我怎样才能获得order_by(B.B_version)

1 个答案:

答案 0 :(得分:0)

正如我在之前对您的问题的回复中所提到的,这不是一个好的模型设计。由于A_Name和A_Version在A类中是唯一的,因此您应该在B类中创建外键以引用A类的ID。如果您这样做,您的所有查询都会更容易,因此您不必发布所有这些这里有问题。

这是最后一次。删除B类中的Name和Version外键:

class A(models.Model):
    A_version = models.DecimalField(max_digits=4, decimal_places=0)
    A_name = models.CharField(max_length=32, blank=True)
    A_type    = models.CharField(max_length=32, blank=True)

    class Meta:
        unique_together(A_version,A_name)

class B(models.Model):
    a = models.ForeignKey(A) #Reference the A.id
    last_reported_time= models.DecimalField(max_digits=4, decimal_places=0)

obj = A.objects.filter(A_type="Vendor").annotate(last_time=Max('B__last_reported_time')).
    order_by('A_name','A_version')

更新:由于模型无法更改,请尝试以下操作:

class A(models.Model):
    A_version = models.DecimalField(max_digits=4, decimal_places=0)
    A_name = models.CharField(max_length=32, blank=True)
    A_type    = models.CharField(max_length=32, blank=True)

    unique_together(A_version,A_name)

class B(models.Model):
    B_version = models.ForeignKey(A, to_field='A_version') #Note the to_field
    B_name    = models.ForeignKey(A, to_field='A_name')   #Note the to_field     
    last_reported_time= models.DecimalField(max_digits=4, decimal_places=0)

    unique_together(B_version,B_name)

obj = A.objects.filter(A_type="Vendor").
    values('A_name','A_version').annotate(last_time=Max('B__last_reported_time')).
    order_by('A_name','A_version')