user3115655
user3115655

Reputation: 109

How to order by model property value?

How to order by model property?

class Item(models.Model):
    name = models.CharField()
    check_permission = models.BooleanField()
    remove_permission = models.BooleanField()
    ...
    
    @property
    def permissions_count(self) -> int:
        count = 0
        if self.check_permission:
            count += 1
        if self.remove_permission:
            count += 1
        return count


qs = Item.objects.all()
if order_by == 'permissions_count':
    qs = qs.order_by('permissions_count')
return qs

I see this error:

Cannot resolve keyword 'permissions_count' into field. Choices are:

Upvotes: 1

Views: 123

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476557

You can annotate the Items and then order by that number:

from django.db.models import ExpressionWrapper, F

qs = Item.objects.annotate(
    num_permissions=(
        Cast('check_permission', output_field=IntegerField()) +
        Cast('remove_permission', output_field=IntegerField())
    )
).order_by('num_permissions')

Upvotes: 1

ruddra
ruddra

Reputation: 51948

You can use conditional annotation to annotate the values in the queryset, then order by it. For example:

from django.db.models import Case, When, IntergerField, Value, Q

Item.objects.annotate(permission_count=Case(
     When(Q(check_permission=True)&Q(remove_permission=True), then=Value(2)),
     When(Q(check_permission=True)|Q(remove_permission=True), then=Value(1)),
     default=Value(0),
     output_field=IntergerField())
).order_by('permission_count')

Upvotes: 1

Related Questions