Django filterset - 一对多查询

时间:2017-05-28 16:48:47

标签: python django-models django-queryset

我有一对多的关系建模如下:

class Client(models.Model):
    name = models.CharField....
    ...

class Contract(models.Model):
    client = models.ForeignKey(Client)
    type = models.IntegerField()
    start_date = models.DateField(null=True, blank=True)
    ...

我想构建一个有效的查询集,它返回最新的客户端(即具有最新开始日期的客户端)contract.type等于5.

恐怕我在试图解决这个问题时正在挣扎。

有人可以帮忙吗?

如果不可能,那么我正在考虑向客户添加一个字段,该字段是与最新合同的一对一关系,并在每次修改合同时保持这一点。然后我可以简单地使用该字段进行搜索。

最后我选择了以下内容,如果可以优化,请告诉我 - ta。

   # this function is called by django-filter
   # its purpose is to remove any clients where the contract with the most recent start date
   # does not have a type that matches the value parameter
   def filter_contract_type(self, queryset, name, value):
       # for each client get the contract with the latest start date
       # if that contract has a type that matches the value parameter, then hold on to the pk of its parent
       # finally strip out any clients that are not in this list, from the queryset django-filter passed in and then return it
       client_ids = []
       value = int(value)
       for client in queryset:
           con = Contract.objects.filter(client=client).order_by('start_date').last()
           if con is not None and con.type == value:
               client_ids.append(con.client.id)

       return queryset.filter(pk__in=client_ids)

1 个答案:

答案 0 :(得分:0)

对不起,因为我没有更好的方法,但你可以尝试:

# Get ez list
Cs = Contract.objects.filter(type = 5).order_by(start_date)
# and run the loop to get the 5 dif cl id
cl_ids= []
num = 0
for c in Cs:
   if c.client_id not in cl_ids:
      cl_ids.append(c.client_id)
      if len(cl_ids) > 4:
          break