2017-04-12 62 views
0

我有2个简单的模型:Claim和ClaimStatus。声明可以有许多状态(例如,1:尚未分析,2:正在分析,3:已分析),所有这些状态都与数据库中的claim_id和creation_date一起记录下来。 这里的兴趣模型 - ClaimStatus - 创建方式如下:Django + postgres:orderby + distinct + filter() - 奇怪的行为

class ClaimStatuss(models.Model): 
    status = models.IntegerField(choices=investigated_choices, default=1) 
    claim_id = models.ForeignKey('Claim', to_field='claim_id') 
    creation_date = models.DateTimeField(auto_now=True) 

我的目标是选择的权利要求和他们的最后(=激活)状态进行过滤,以显示如。正在此刻的分析,使用建议氟里昂这个线程的所有情况: Django orm get latest for each group

,使其更简单,我有我的数据库中仅有2对象:

id: 6,claim_id: 578, status: 2, date: 2017-04-12 16:55:25.371014+00:00 
id: 7,claim_id: 578, status: 3, date: 2017-04-12 17:04:06.944270+00:00 

我做了以下内容:

  1. 选择所有ClaimStatuss对象和组他们有最新的一个每个claim_id(只有一个在这个例子中):
statuses = ClaimStatuss.objects.all().order_by('claim_id','-creation_date').distinct('claim_id')
  • 我检查,如果只有一个,最新的元件已被选择用于查询集:
  • statuses.get().status 
        3
  • 现在我筛选此一个元素的查询集,只留下对象,其中包含状态= 2
  • statuses.filter(status=2).get().status 
        2

    而且我看到,包含与状态“3”,AF只是一个对象我的查询ter过滤也发现状态为“2”的对象!

    我认为这是第一个命令的问题,但这是一个预期的行为(如果是这样,我做错了什么/我应该怎么做才能使它)或一些错误?

    其他详细信息:

    检查状态= 3带来积极的结果太(所有其他状态不)

    >>> statuses.filter(status=3).get().status 
    3 
    

    古怪的是,我可以在状态变量,执行GET方法,只是证实含有2个不同的对象:

    >>> statuses.get().status 
    3 
    

    的ForeignKey的是不是这里的问题 - 我试图将其更改为字符串和行为是一致的。

    回答

    1

    您对distinct()调用和其他过滤器之间的交互感到困惑。

    所有distinct('claim_id)将会确保每个索赔项目返回一个项目。但你只要求一件物品;当你为状态= 2添加过滤器时,你仍然只能得到claim_id不同值的一个项目。如果你不添加过滤器,那么这与你所得到的不一样。

    +0

    哦,我现在明白了,谢谢。你知道解决问题的方法吗?即每个索赔只返回一个元素,而不是“确保”每次都返回一个元素? – Dominix

    +0

    好的,我通过添加一个名为Is_current的布尔列来解决问题,该列存储有关给定状态最新的信息。然后,添加新状态时,在添加新对象(使用Is_current = True)之前,它将Is_current列值更改为前一状态(带“True”的状态)的False。最后,我只是用Is_current = True过滤值。 – Dominix

    +0

    好的解决方案。问题是,像这样的查询动态依赖于子查询,而Django只是[添加了对[增加]的支持)(https://docs.djangoproject.com/en/1.11/ref/models/expressions/#subquery-expressions)(在1.11中)。 –