Juliette Dupuis
Juliette Dupuis

Reputation: 1037

Move an element inside a Queryset

I have a queryset in my django view.

I would like to change the position of one of the item in order it to be the first element of the queryset.

Any idea on how to do that?

EDIT:

I have a queryset:

   qs = UserProfile.objects.filter(myfilter=whatever)

I know that inside this queryset I have:

   specific_user.userprofile

What I want to do is to put the user.userprofile in first position into my queryset because I use this queryset in a loop in my template:

    {% for i in qs %}
    <div> i.name </div>

And I want to be sure that the first name of the list is the name of the specific_user.

Upvotes: 2

Views: 2198

Answers (2)

gdvalderrama
gdvalderrama

Reputation: 806

Since Django 1.8 you have Conditional Expressions which you can use to define a specific order.

You would set a special case when the UserProfile is specific_user.userprofile:

qs = UserProfile.objects.filter(myfilter=whatever)\
.order_by(Case(When(pk=specific_user.userprofile.pk, then=0), default=1)))

We set the value of 0 in the special case, and 1 as default. This way the specified user would always show first.

Upvotes: 4

acjay
acjay

Reputation: 36641

QuerySet objects in Django are abstract representations of the result of database queries. Generally speaking, it represents SQL that might later be executed when specific objects from the queryset are requested, but until that happens, no queries are executed. So you can't really think of a queryset like a list, which might be arbitrarily reordered. You can request the objects in your queryset to be sorted using its order_by method, so if you want a particular object to come first, it must have some sortable attribute on the DB side of things by which it can be ordered. This could be a column or a value calculated from its columns using F expressions.

But, for your needs, it seems like you could just make a list of your queryset in your view:

profiles = [specific_user.userprofile] + [profile for profile in UserProfile.objects.filter(myfilter=whatever).exclude(id=specific_user.userprofile.id)]

Add that to your context and iterate over it instead of the original queryset in your template.

Upvotes: 6

Related Questions