因此,我有一个看起来像这样的模型:

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

class Entries(models.Model):
  name = models.ForeignKey(Names)
  date = models.DateField()


数据看起来像这样

name   |  date

name_1 |  2011-06-01
name_2 |  2011-03-01
name_3 |  2011-02-01
name_1 |  2010-06-01
name_2 |  2010-03-02
name_3 |  2010-02-01
name_4 |  2009-07-01


我想用日期查询条目,并在小于或等于日期的位置获取每个名称记录一次。因此,如果我查询日期为2011-06-01的结果,我希望返回此值:

name_1 | 2011-06-01
name_2 | 2011-03-01
name_3 | 2011-02-01
name_4 | 2009-07-01


我的假设是,这可以解决问题:

date = datetime(year=2011, month=06, day=01)
results = Entries.objects.filter(date__lte=date).order_by('date').distinct('name')


但是,我一直在那里重复输入名称。

有什么提示吗,朋友?

编辑:该解决方案由Gareth Rees提供。我必须对其稍作修改,但它看起来像这样:

sql = """myapp_entries.id = (SELECT E.id from myapp_entries AS E
                             WHERE E.name_id = myapp_names.id AND
                             '"""+date.strftime('%Y-%m-%d')+"""'
                             ORDER BY E.date DESC
                             LIMIT 1)'''

results = (Entries.objects
           .extra(where = [sql])
           .filter(date__lte = date)
           .order_by('name', 'date'))

最佳答案

根据您需要的结果,有两种方法。

(1)如果您不介意以字典形式(而不是Entries对象)获得结果,则可以将annotatevalues组合使用以对结果进行分组。在这种情况下,您想要的查询将如下所示:

from django.db.models import Min
results = (Entries.objects
           .filter(date__lte = date)
           .values('name')
           .annotate(date = Min('date'))
           .order_by('name', 'date'))


(2)如果需要将结果作为Entries对象取回,则可以使用extra仅选择名称相同的所有条目中最早的条目:

sql = '''id = (SELECT E.id FROM myapp_entries AS E
                WHERE E.name_id = myapp_entries.name_id
                ORDER BY E.date
                LIMIT 1)'''
results = (Entries.objects
           .extra(where = [sql])
           .filter(date__lte = date)
           .order_by('name', 'date'))

关于python - 使用Django获取具有尽可能接近日期的不同条目的查询集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10257271/

10-16 12:03