How to annotate median value to django queryset

十年热恋 提交于 2020-06-29 03:56:26

问题


I have 2 models Puzzle and Play. for each play I have a rating. I would like to annotate to a Puzzle queryset the median rating value for all corresponding plays.

class Puzzle(models.Model):
    name = models.CharField(max_length=255)

class Play(models.Model):
    puzzle = models.ForeignKey(Puzzle, on_delete=models.CASCADE,related_name='plays')
    rating = models.IntegerField(default=-1)
    puzzle_completed = models.BooleanField(default=None, blank=False, null=False)

I know how to count:

Puzzle.objects.annotate(nb_sucesses=Count('plays', filter = Q(plays__puzzle_completed=True), distinct = True),)

and I expected getting the median in a similar way:

Puzzle.objects.annotate(rating_median=Median('plays__rating', filter = Q(plays__puzzle_completed=True), distinct = True),)

however, apparently due to my Django development environnment database (sqlite), I'm not able to do that.

From what I infered from the following info https://mariadb.com/kb/en/median/, in my production environment(MariaDB), this approach should work (but I didn't tested it yet)

My current understanding (based on different internet searches) is that I should be able to use Django Func() function to use a custom Median function (following that model ?) that would either call Median if in production, or a more complicated sql raw query if in Development (based on this one ? or on this one?).

But after a few hours, I must admit I am out of my depth here.

Anyone could please help me connect the dots ?


回答1:


There is no Median implementation in Django as it is not implemented in PostgreSQL.

You can run median on MariaDB 10.3.3+ as raw query or write yourself an aggregate function inside Django for your custom needs which will then translate to same query using ORM

You should definitely have same db type on production and dev environment to minimize bugs due different environment ( suggesting also to use tools like docker)




回答2:


For how to do this when using PostgreSQL refer to my answer at Django & Postgres - percentile (median) and group by.

One can create a Median child class of Aggregate, which then behaves like the other aggregation functions.



来源:https://stackoverflow.com/questions/59707982/how-to-annotate-median-value-to-django-queryset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!