I have Django objects set up like:
class Example(models.Model):
count = models.CharField(default="0")
So if I have some objects ex1
, ex2
, ex3
, ex4
that have count of -1, 0, 5, -6 respectively. I want to be able to query the objects and sort them into the order [0, 5, -6, -1]
where any zeros come first, then positives, then negatives while also going in ascending order for each section. I was thinking about using something like Example.objects.order_by('count')
but did not find a way to do that with a custom function like this.
The other route I was looking at was something like below:
objs = Example.objects.all()
sorted_objs = sorted(objs, key = lambda o: int(o.count))
Is there a way to use the sorted method to sort the zeros first? I was unable to find one.
The final way I am using is:
objs = Example.objects.all()
zero_objs = []
positive_objs = []
negative_objs = []
for obj in objs:
if obj.count == 0:
zero_objs.append(obj)
elif obj.count < 0:
negative_objs.append(obj)
else:
postitive_objs.append(obj)
sorted_objs = zero_objs + sorted(postitive_objs) + sorted(negative_objs)
This works but seems like it's not the best way to do this, so any ideas would be great. As a side note, I am aware the count attribute would be better stored as an integer field, but I would like to accomplish this while keeping it a char field.
if you want to select by Descending just add minus operator before the attribute field or if you want to select by Ascending no need minus operator.
first, which takes a query set and returns the first element, or None if the query set was empty. Instead of writing this: try: object = MyModel.objects.get(key=value) except model.DoesNotExist: object = None.
You can use case
to add a new field for ordering purposes:
from django.db.models import Case, IntegerField, Value, When
Example.objects.annotate(
o=Case(
When(count=0, then=Value(0)),
When(count__gt=0, then=Value(1)),
When(count__lt=0, then=Value(2)),
output_field=IntegerField(),
),
).order_by('o', 'count')
Explanation:
Order clause will be composed by both: the "new field", count
. With "new field" you raise set of rows with count = 0 to top, then set of positive numbers at last set of negatives. The second field, count
, do the ascending sort for each set.
Disclaimer:
Be aware, this is not an index friendly solution! If you need performance, then, just create this new field on model and figure out it before save.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With