Queryset只获取每个外键的一条(任意)记录

时间:2013-04-23 02:45:32

标签: python django django-1.4

说我有以下型号:

class Manufacturer(Model):
    name = models.CharField(max_length=255)
    origin = models.CharField(max_length=255)

class Car(Model):
    model = models.CharField(max_length=255)
    manf = models.ForeignKey(Manufacturer, related_name="cars")

然后我想运行以下查询:

usa_manfs = Manufacturer.objects.filter(origin='USA')
usa_manf_cars = Car.objects.filter(manf__in=usa_manfs)

但是我只想在QuerySet中为每个制造商提供1辆汽车。

我知道我可以走另一条路,做一些像usa_manfs.cars[0]这样的事情但是这不是说我需要为每个制造商查询以获得所有相关车辆吗?

为了澄清,我不需要对每个制造商检索哪个Car实例进行任何控制。我只需要得到一份汽车清单,其中制造商是独一无二的。

现在的解决方案

经过深思熟虑之后,我决定选择Python解决方案并防止循环重复。

我正在使用的数据可能在ForeignKey字段上具有相对较少的重复项(其中我的示例可能不会支持),因为我无法获得将其保留在Django中的解决方案ORM,我只是跟踪ForeignKey并在循环中排除重复。因为无论如何我都在循环它们,我认为我不会创造更多的整体工作。

e.g:

cars = list(Car.objects.all())
final_list = []
used_before = []

for car in cars:
    if not car.manf_id in used_before:
        used_before.append(car.manf_id)
        doStuff(car)
        final_list.append(car)

如果有更好的解决方案,我会接受。

2 个答案:

答案 0 :(得分:1)

  

我只需要以Cars列表结束   Manufacturer是唯一的。

如何使用distinct

cars = Car.objects.order_by('manf').distinct('manf')

由于上述仅支持PostgreSQL,因此您必须解决它:

m = Manufacturer.objects.all()

cars = []
for i in m:
    if Car.objects.filter(manf=i).exists():
       cars.append(Car.objects.filter(manf=i).order_by('?')[1])

这将为每个制造商提供一辆随机汽车。

答案 1 :(得分:0)

我不确定我们怎么能用orm做到这一点。可以告诉我们如何通过直接sql实现它:

from django.db import connection
cursor = connection.cursor()

cursor.execute("select c.model from myapp_car c, myapp_manufacturer m where m.origin='USA' and m.id=c.manf_id group by m.id")