|
有没有一种简单的方法可以根据列中具有最大值/最小值的记录来过滤Django查询?我本质上是在问这些问题,但是是在Django ORM的特定上下文中。& E* ?. m2 M0 Y5 i( i
例如) r/ a" ?0 f" m( S
假设我有一个模型可以存储每个人的电话号码的历史值。0 A7 W. X" `( r5 X4 ?. h* _$ j
class Person(models.Model):
$ w* k& c8 R$ | name = models.CharField(max_length=100)7 p4 @: L! s- B
phone = models.CharField(max_length=100)
% N9 K& b0 M8 t4 J9 M' @ created = models.DateTimeField(auto_now_add=True)" O, m2 T1 |0 Z( C; S
与记录:, F/ ]5 X) [' D; O! G
Person(name='Jim',phone='123-456-9870', created=datetime(2005,1,2,4,2)): r1 l, p' Z; F& i6 J
Person(name='Jim',phone='329-802-9870', created=datetime(2006,9,2,7,8))) |" p4 ?7 Z" u
Person(name='Sue',phone='324-345-3450', created=datetime(2008,7,4,6,1))
# H+ \2 i' j& m$ S m现在说我想找到每个人的最新电话号码。
8 C& s4 y% a: r) y5 a在SQL中,通常必须使用子查询来计算最大值:' A, Q% E! W+ `+ w& q
SELECT p1.name, p1.phone, p1.created( r, a. G4 O8 L8 ^
FROM person_person p1, (' r3 H I) G; t0 e& u) ^, ^
SELECT name, MAX(created) AS max_created
0 p/ T" }' F8 T" I9 c. { FROM person_person# U+ l, k/ {. Q: T" ^4 k; U
GROUP BY name
& c2 R1 C3 {7 i, {2 Y) AS p2
, E( f3 p; F2 }* C4 }8 ZWHERE p1.name = p2.name AND p1.created = p2.max_created5 [ _ t! v2 a3 T8 B9 n5 n* c& c
Django中是否有任何机制可以简化此过程?
' }5 E" t4 P1 X# }. o G. U我在后端使用PostgreSQL,因此任何依赖PostgreSQL特定功能的想法或解决方案都将有所帮助。* K5 S- x. w/ N3 i
6 \! {) u5 [9 @: A; Y) l解决方案:) ~( T2 C! g1 p- G7 l7 N
5 b8 j' w" @0 h g1 M
4 M J* s% r% O: R& Z& X
' @+ q) i* {7 F! c$ @ 您可能只想在这里使用原始SQL,raw()manager方法可简化此操作,使您可以从查询中返回模型实例。唯一的技巧是原始查询需要包含主键。这可能应该对您有用(除非您将主键设置为以外的其他值id):
9 }6 Y& j( H9 [latest_phone_numbers = Person.objects.raw('''
" I: M; p9 r; u! L0 C+ sSELECT p1.id, p1.name, p1.phone, p1.created
: W/ U1 ]0 M* t+ rFROM person_person p1, (# Q) c; P( i& B5 c" G
SELECT name, MAX(created) AS max_created- s0 Q% H$ w8 M5 k* h8 j K0 u. u
FROM person_person) \. {# P# V1 A5 u: p, h& f
GROUP BY name6 b6 Z$ f! s5 r) U% [
) AS p22 H/ ^5 W# R8 D6 t" h
WHERE p1.name = p2.name AND p1.created = p2.max_created
2 X, j1 T3 P2 G& j0 O''') |
|