252
See this. Your code would be something like the following:
from django.db.models import Max
# Generates a "SELECT MAX..." query
Argument.objects.aggregate(Max('rating')) # {'rating__max': 5}
You can also use this on existing querysets:
from django.db.models import Max
args = Argument.objects.filter(name='foo') # or whatever arbitrary queryset
args.aggregate(Max('rating')) # {'rating__max': 5}
If you need the model instance that contains this max value, then the code you posted is probably the best way to do it:
arg = args.order_by('-rating')[0]
Note that this will error if the queryset is empty, i.e. if no arguments match the query (because the [0]
part will raise an IndexError
). If you want to avoid that behavior and instead simply return None
in that case, use .first()
:
arg = args.order_by('-rating').first() # may return None
92
Django also has the โlatest(field_name = None)โ function that finds the latest (max. value) entry. It not only works with date fields but also with strings and integers.
You can give the field name when calling that function:
max_rated_entry = YourModel.objects.latest('rating')
return max_rated_entry.details
Or you can already give that field name in your models meta data:
from django.db import models
class YourModel(models.Model):
#your class definition
class Meta:
get_latest_by = 'rating'
Now you can call โlatest()โ without any parameters:
max_rated_entry = YourModel.objects.latest()
return max_rated_entry.details
- [Django]-Django: How can I create a multiple select form?
- [Django]-Django FileField upload is not working for me
- [Django]-Sending post data from angularjs to django as JSON and not as raw content
59
Iโve tested this for my project, it finds the max/min in O(n) time:
from django.db.models import Max
# Find the maximum value of the rating and then get the record with that rating.
# Notice the double underscores in rating__max
max_rating = App.objects.aggregate(Max('rating'))['rating__max']
return App.objects.get(rating=max_rating)
This is guaranteed to get you one of the maximum elements efficiently, rather than sorting the whole table and getting the top (around O(n*logn)).
- [Django]-How to manage local vs production settings in Django?
- [Django]-Django import error โ No module named core.management
- [Django]-How do I integrate Ajax with Django applications?
12
sol 01:
from .models import MyMODEL
max_rating = MyMODEL.objects.order_by('-rating').first()
sol 02:
from django.db.models import Max
from .models import MyMODEL
max_rating = MyMODEL.objects.aggregate(Max('rating'))
- [Django]-Best practices for adding .gitignore file for Python projects?
- [Django]-Table thumbnail_kvstore doesn't exist
- [Django]-Django annotation with nested filter
8
If you also want to get a value other than None
in case the table is empty (e.g. 0), combine Max
with Coalesce:
from django.db.models import Max, Value
from django.db.models.functions import Coalesce
max_rating = SomeModel.objects.aggregate(
max_rating=Coalesce(Max('rating'), Value(0))
)['max_rating']
- [Django]-Django Background Task
- [Django]-Do django db_index migrations run concurrently?
- [Django]-How can I get the full/absolute URL (with domain) in Django?
3
To maybe improve on @afahim answer with regards to @Raydel Miranda comment, if you want a random comment. If you want all, then use just the filter
from django.db.models import Max
# Find the maximum value of the rating and then get the record with that rating.
# Notice the double underscores in rating__max
max_rating = App.objects.aggregate(Max('rating'))['rating__max']
return App.objects.filter(rating=max_rating).first()
- [Django]-Django: reverse accessors for foreign keys clashing
- [Django]-Pulling data to the template from an external database with django
- [Django]-Django F() division โ How to avoid rounding off
1
maybe it will help someoneโs trouble, in CBV
def get_queryset(self):
sorgu = Sunum.objects.values('id', 'firma', 'projeadi', 'sunumdurum__durum', 'sunumdurum__aciklama'
).annotate(max_rank=Max('sunumdurum__kayittarihi'))
szlk={}
for sor in sorgu :
ana = sor['id'], sor['firma'], sor['projeadi']
dana = sor['sunumdurum__durum'], sor['sunumdurum__aciklama'], sor['max_rank']
szlk.setdefault(ana, dana)
return szlk
- [Django]-How do you log server errors on django sites
- [Django]-How do I clone a Django model instance object and save it to the database?
- [Django]-How to put comments in Django templates?
1
For future readers you can use annotate
instead of aggregate
if you need the record / other fields and not just the max value.
i.e equivalent to this sql query
SELECT
first_name,
last_name,
Max(height) max_height
FROM patients;
Now one problem is passing an aggregate function in annotate will trigger a group by
from django.db.models import Max
Patients.objects.values('height').annotate(max_height=Max('height'))
>>>
SELECT "patients"."height",
MAX("patients"."height") AS "max_height"
FROM "patients"
GROUP BY "patients"."height"
The workaround is to use the Func expression
from django.db.models F, Func
Patients.objects.annotate(max_height=Func(F('height'), function='Max'))\
.values('first_name', 'last_name', 'max_height')
>>>
SELECT "patients"."first_name",
"patients"."last_name",
Max("patients"."height") AS "max_height"
FROM "patients"
see this if you need to do this in a subquery
- [Django]-Where can I find the error logs of nginx, using FastCGI and Django?
- [Django]-Multiple Database Config in Django 1.2
- [Django]-Django Rest JWT login using username or email?