Eu Chi
Eu Chi

Reputation: 563

Order a django queryset with specific objects first

I have a list of users displaying in templates like the following.

{% for u in users_list %}

    {{u.name}}

{% endif %}

Is there a way to rank two or more users at the top If I want to?

For instance with one user, when the current user visits that list, I can rank him in the top without a specific ordering by excluding me before sending the variable to template.

1) me
2) user2
3) user3

Upvotes: 7

Views: 4487

Answers (3)

Greg
Greg

Reputation: 10352

If you want to order specific objects by id at the top of a queryset, you can order on a conditional expression - for example, to put the current user at the top, and order other users by name:

from django.db.models import Case, When
from django.contrib.auth.models import User

users = User.objects.order_by(
    Case(When(id=request.user.id, then=0), default=1),
    'last_name',
    'first_name'
)

To put multiple objects at the top, just adjust the When condition:

ids_at_top = [1, 2]
users = User.objects.order_by(
    Case(When(id__in=ids_at_top, then=0), default=1))

I would also consider though whether you can achieve what you want via simpler means - for example you could get the current user, exclude them from the main queryset, and then display separately in the template, like this

# in the view
current_user = request.user
users = User.objects.exclude(id=current_user.id)

# in the template
{{ current_user.name }}
{% for u in users %}
  {{ u.name }}
{% endif %}

Upvotes: 23

Karim N Gorjux
Karim N Gorjux

Reputation: 3033

Usign the queryset you can order your users_list based on the fields in the User. For this purpose you have the sort method in the queryset. In your case seems to me you need to add a field so you can sort by that field. For example you add a rank field default 0 and than add a value for the hightest rank.

The full example is defined here: https://docs.djangoproject.com/en/2.1/topics/auth/customizing/#a-full-example

In your CustomUserMdel just add a field rank = models.IntegerField(default=0)

Then in your view you need to sort by rank:

from django.contrib.auth import get_user_model

User = get_user_model()

# in your view...
user_list = User.objects.all().sort_by('rank')

Upvotes: 0

Taylor
Taylor

Reputation: 1253

In your view create a list of users that you want to display. In order to display the current user you can use request.user to get the current user and append them to the list followed by the rest of the users. In your template you would do

<ol type="1">
{% for u in users_list %}

    <li>{{u.name}}<li>

{% endif %}
</ol>

should out what you are looking for

Update example

user_list = list(Users.objects.filter(name="Test")) #Or how ever you want to get the users.
user_list.insert(0,request.user)

if you wanted to get another individual you would just get the user using

another_person = User.objects.get(id=some_id)
user_list.insert(0,another_person)

Upvotes: 1

Related Questions