Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 531
Eu Chi Avatar asked Aug 27 '18 21:08

Eu Chi


People also ask

What does First () do in Django?

first, which takes a query set and returns the first element, or None if the query set was empty. Note, that this is not identical. The get method will ensure that there is exactly one row in the database that matches the query.

How you combine multiple QuerySet in a view?

Use union operator for queryset | to take union of two queryset. If both queryset belongs to same model / single model than it is possible to combine querysets by using union operator. One other way to achieve combine operation between two queryset is to use itertools chain function.

How do I combine QuerySet?

You can also use the chain() method from the Itertools module, which allows you to combine two or more QuerySets from different models through concatenation. Alternatively, you can use union() to combine two or more QuerySets from different models, passing all=TRUE if you want to allow duplicates.


2 Answers

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 %}
like image 98
Greg Avatar answered Nov 10 '22 21:11

Greg


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)
like image 43
Taylor Avatar answered Nov 10 '22 19:11

Taylor