有没有一种简单的方法来根据哪个记录在列中具有最大/最小值来过滤Django查询?我基本上是在问这些 问题,但是在Django的ORM的特定背景下.
例如
假设我有一个模型,用于存储每个人电话号码的历史值.
class Person(models.Model):
name = models.CharField(max_length=100)
phone = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)
记录:
Person(name='Jim',phone='123-456-9870', created=datetime(2005,1,2,4,2))
Person(name='Jim',phone='329-802-9870', created=datetime(2006,9,2,7,8))
Person(name='Sue',phone='324-345-3450', created=datetime(2008,7,4,6,1))
Run Code Online (Sandbox Code Playgroud)
现在说我想找到每个人最近的电话号码.
在SQL中,我通常必须使用子查询来计算最大值:
SELECT p1.name, p1.phone, p1.created
FROM person_person p1, (
SELECT name, MAX(created) AS max_created
FROM person_person
GROUP BY name
) AS p2
WHERE p1.name = p2.name AND p1.created = p2.max_created
Run Code Online (Sandbox Code Playgroud)
Django中是否有任何可以简化此操作的机制?
我在我的后端使用PostgreSQL,因此任何依赖PostgreSQL特定功能的想法或解决方案都会有所帮助.
想象一下,我们有Django ORM模型Meetup,其定义如下:
class Meetup(models.Model):
language = models.CharField()
date = models.DateField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)
我想为每种语言取一个最新的聚会.
看起来你可以使用Django Aggregates来简化这个查找:
Meetup.objects.annotate(latest_date=Max("date")).values("language", "latest_date")
Run Code Online (Sandbox Code Playgroud)
在我看来,这应该取得每种语言的"最新"聚会.但事实并非如此:
>>> Meetup.objects.create(language='python')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='python')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node')
<Meetup: Meetup object>
>>> Meetup.objects.create(language='node')
<Meetup: Meetup object>
>>> Meetup.objects.annotate(latest_date=Max("date")).values("language", "latest_date").count()
4
Run Code Online (Sandbox Code Playgroud)
我期望得到两个最新的Python和Node聚会!
如何构建一个只能获取每种语言的最新聚会的查询?
PS.我使用MySQL作为我的后端.
我有一个数据框:
`exp_no` 'time' 'price'
Run Code Online (Sandbox Code Playgroud)
1 0:00:00 20.0
1 7 days 45.0
1 15 days 100.0
2 0:00:00 20.0
2 7 days 45.0
2 15 days 100.0
Run Code Online (Sandbox Code Playgroud)
对应的Django模型:
class StData(models.Model):
exp_no = models.ForeignKey(StIndex, on_delete=models.CASCADE)
time = models.DateTimeField()
price = models.DecimalField(max_digits=10, decimal_places=2)
Run Code Online (Sandbox Code Playgroud)
我想制作一个较小的表,其中包含 exp_no、max_time 和相应的价格,如下所示:
`exp_no` 'time' 'price'
Run Code Online (Sandbox Code Playgroud)
1 15 days 100.0
2 15 days 100.0
Run Code Online (Sandbox Code Playgroud)
在 pandas 中,我会df.groupby('exp_no')['time', 'price'].max().reset_index()
做得到想要的表。
在 Django ORM 注释中,如果我这样做,可以获得相同的结果(或查询集):
qs.values('exp_no').annotate(max_time=Max('time')).order_by()
Run Code Online (Sandbox Code Playgroud)
它给了我exp_no和时间,但我也想得到相应的价格。我已经在SO中查看了这个答案:Django orm getlatest for every group
但不知道如何得到价格。将 Django 2.0 与 sqlite3 结合使用。
我很感激任何帮助。
按照这个问题,我试图获取每个 group_by 标准的前 10 条记录,但 Django 返回此错误:
from django.db.models import F, Window
from django.db.models.functions import RowNumber
Purchases.objects.annotate(row_number=Window(
expression=RowNumber(),
partition_by=F('customer'),
order_by=F('field_of_interest').desc()
)
).filter(row_number=10)
Run Code Online (Sandbox Code Playgroud)
raise NotSupportedError(
django.db.utils.NotSupportedError: Window is disallowed in the filter clause.
Run Code Online (Sandbox Code Playgroud)
当我删除 .desc() 时,错误消息更改为:
ValueError: order_by must be either an Expression or a sequence of expressions.
Run Code Online (Sandbox Code Playgroud)
我正在使用 PostgreSql。这是一个错误还是我在查询中的某个地方错了?