考慮下面的例子:在Django創建自定義查詢1.8
class Customer(models.Model):
first_name = models.CharField()
last_name = models.CharField()
rental_date = models.DateTimeField()
rented_car = models.ForeignKey(Car)
class Car(models.Model):
color = models.CharField()
reg_no = models.IntegerField()
我希望將全部自駕租賃(假設客戶可以不租一路車多,但客戶可以租一輛車多次)並且每個組只返回最近的rental_date
的租賃,並訪問客戶名稱和車輛reg_no
。
的SQL會是這個樣子:
SELECT * FROM Customer c where rental_date = (SELECT max(rental_date) FROM Customer WHERE rented_car_id = c.rented_car_id);
或像這樣:
SELECT *, max(rental_date) from Customer group by rented_car;
將導致查詢集就會按照客戶FIRST_NAME或汽車reg_no和其他過濾器來分類的可能應用(例如,只獲取名稱以'A'開頭的藍色汽車或客戶)。我已經嘗試
事情:
聚合:
from django.db.models Max
Customer.objects.values('rented_car').annotate(max_start_date=Max('rental_date'))
但這返回包含Car
對象的主鍵的字典。我也需要Customer
的值。修改查詢以包含來自Customer
(.values('rented_car', 'first_name')
)的字段將更改SQL並更改最終結果。
我所用的第二種方法是raw
:
Customer.objects.raw("""SELECT * FROM Customer c where rental_date = (SELECT max(rental_date) FROM Customer WHERE rented_car_id = c.rented_car_id)""")
但這返回一個RawQuerySet實例不允許進一步的過濾或排序。此外,Customer.objects.filter(...).raw(...).order_by(...)
將不會工作,因爲raw
方法將覆蓋過濾。
可能返回查詢設置,並允許額外的濾波另一種方法是extra
:
Customer.objects.filter(...).extra(select={
'customer_instances': """SELECT *, max(rental_date) from Customer group by rented_car"""
})
但他總是會返回一個錯誤(1241, 'Operand should contain 1 column(s)')
。另外,從這個discussion我發現QuerySet.extra(...)將不再支持,而應該使用aggregation
。
您的模型/模式對我來說似乎很奇怪 - 我會在'Car'和'Customer'中使用一箇中間的'Rent'模型,日期和外鍵。 –
謝謝你的迴應。但是,這與我正在研究的項目的情況類比。由於NDA協議,我不能提供任何更多的細節,但是,另一種模式不適合。 –
爲什麼你的項目不接受一個理智的數據庫設計?另外,如果你有嚴格的NDA和東西,那麼就會涉及金錢,所以聘請一位熟悉Django和SQL的顧問,並且不要過來請求其他人免費工作。 –