简体   繁体   中英

How to search for the mode of a field in a one to many relationship in django's ORM?

I have this one to Many relationship between dish and restaurant.

SPICINESS_CHOICES = (
    ("M", "Mild")
    ("H", "Hot")
    ("SH", "Super hot")
)
class Restaurant(Model):
    name = models.CharField(max_length=50)



class Dish(Model):
    restaurant = models.ForeignKey(Restaurent)
    name = models.CharFiedl(null=True, max_length=50)
    price = models.IntegerField(max_length=10, null= False)
    spicy = models.CharField(null= True, choices=SPICINESS_CHOICES)

I would like to be able to search Restaurants for the most occurring spiciness of their dishes or the mode of the spiciness of their dishes https://en.wikipedia.org/wiki/Mode_(statistics) . Django does not seem to have functionality to implement this easily. So let's say we have three restaurants, Anny's, Domino and Verspucie.

Anny's has different 8 dishes of which 2 dishes are labeled as being Hot, all other dishes are labeled as Mild, since the owner wants to be able to have a varied menu for children

Domino has 9 different dishes of which 5 dishes are labeled as being Hot, 2 as being Super Hot and 2 as being mild.

Verspucie has 10 different dishes of which 8 are labeled as being Super Hot, one 1 labeled as Mild and 1 is labeled as Hot.

Because I want to find the correct restaurant from a whole list of restaurants, I would like to be able to search the restaurants for their most occuring spiciness in their dishes. In postgres one could do this using the mode function and then joining this mode value on to the restaurants table. If I would want to have a restaurant which mostly has Super Hot dishes my query would look something like this:

SELECT * FROM "restaurant" LEFT OUTER JOIN (SELECT "dish"."restaurant_id" ,mode() WITHIN GROUP (ORDER BY "dish.spicy") AS "mode_spicy" FROM dish GROUP BY "dish"."restaurant_id") mode_table ON "id"="mode_table"."taxonomy_id") WHERE "mode_spicy"='SH';

This would then yield the Verspucie restaurant since it is the only restaurant which has most of its dishes labeled as Super Hot. But now I would like to do this in the django ORM langauge yet I can't find a mode() function in django.

Edit: I went for the SQL query in the end

    from django.db.models import Count, IntegerField, When, Case
    Restaurant.objects.annotate(
        numcount=Count(Case(
            When(dish__spicy="SH", then=1),
            output_field=IntegerField(),
        ))
    ).order_by("-numcount")

this query will count number of dish have spicy SH each restaurant, And you can order this, checking after this for find restaurant have most SH with your logic

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM