次のようなモデルがあります。
class Review(models.Model):
venue = models.ForeignKey(Venue, db_index=True)
review = models.TextField()
datetime_created = models.DateTimeField(default=datetime.now)
データベースをクエリして、日ごとにグループ化された会場のレビューの総数を取得したいと思います。 MySQLクエリは次のようになります。
SELECT DATE(datetime_created), count(id)
FROM REVIEW
WHERE venue_id = 2
GROUP BY DATE(datetime_created);
Djangoでこれを達成するための最良の方法は何ですか?私はただ使うことができました
Review.objects.filter(venue__pk=2)
ビューで結果を解析しますが、それは私には正しくないようです。
これは動作します(使用したものと同じMySQL固有の関数を使用):
Review.objects.filter(venue__pk=2)
.extra({'date_created' : "date(datetime_created)"})
.values('date_created')
.annotate(created_count=Count('id'))
完全を期すために、extra()は非推奨を目的としているため、このアプローチを使用できます。
from Django.db.models.expressions import DateTime
Review.objects.all().\
annotate(month=DateTime("timestamp", "month", pytz.timezone("Etc/UTC"))).\
values("month").\
annotate(created_count=Count('id')).\
order_by("-month")
これは、Django 1.8で、sqliteデータベースとMySqlデータベースの両方で機能しました。
Extra()
が減価償却されているため、より適切な答えは Trunc のようになります この受け入れられた答え など
今OPの質問は次のように答えられます
from Django.db.models.functions import TruncDay
Review.objects.all()
.annotate(date=TruncDay('datetime_created')
.values("date")
.annotate(created_count=Count('id'))
.order_by("-date")
日付フィールドを格納している場合は、これを使用できます。
from Django.db.models import Count
Review.objects.filter(venue__pk = 2)
.values('date').annotate(event_count = Count('id'))
日時を保存しているので、少し複雑ですが、これは良い出発点になるはずです。集計ドキュメント here を確認してください。
また、カスタム関数を定義できます。
from Django.db.models.expressions import Func
# create custom sql function
class ExtractDateFunction(Func):
function = "DATE" # thats the name of function, the way it mapped to sql
# pass this function to annotate
Review.objects.filter(venue__pk=2)
.annotate(date_created=ExtractDateFunction("datetime_created"))
.values('date_created')
.annotate(created_count=Count('id'))
DBエンジンがDATE関数をサポートしていることを確認してください