Si potrebbe fare due query, una per gli utenti prima che gli utenti attuali, e uno per gli utenti poco dopo:
id = current_user.pk
points = current_user.profile.points
before = User.objects.filter(
Q(profile__points__gt=points) |
Q(profile__points=points, pk__lt=id)
).order_by('-profile__points')[:5]
after = User.objects.filter(
Q(profile__points__lt=points) |
Q(profile__points=points, pk__gt=id)
).order_by('profile__points')[:5]
Si tratta di basi su due query:
- tutti gli utenti con un punteggio superiore a quello dell'utente corrente, o con lo stesso punteggio ma con uno
pk
inferiore.
- Tutti gli utenti con un punteggio inferiore a quello dell'utente corrente o con lo stesso punteggio ma con un numero maggiore
pk
.
Quindi con l'ordine e i limiti corretti è possibile ottenere il risultato. Ovviamente pk
può essere sostituito da qualsiasi altro file, o semplicemente rimosso completamente. In quest'ultimo caso, si può invece considera che l'utente corrente è sempre al primo posto (questo è solo un esempio), e le query diventano:
before = User.objects.filter(
profile__points__gt=points,
).order_by('-profile__points')[:5]
after = User.objects.filter(
profile__points__lte=points,
).exclude(pk=id).order_by('profile__points')[:5]
In alternativa, per ottenere solo l'indice dell'utente corrente nella lista degli utenti ordinati per punti, si potrebbe fare:
id = current_user.pk
points = current_user.profile.points
index = User.objects.filter(
Q(profile__points__gt=points) |
Q(profile__points=points, pk__lt=id)
).count()
Allora la vostra lista di utenti centrato su quella attuale sarà solo:
User.objects.all().order_by('-profile__points', 'pk')[index - 5:index + 6]
Questa alternativa potrebbe essere più lento se si hanno un sacco di utenti, dato che l'intera lista di utenti prima di quella attuale deve essere valutata, ma non l'ho verificata.
che dovrebbe funzionare. Qualche idea su come posso ottenere la "posizione" degli utenti in quell'ordine? –
@ Nuno_147 È possibile contare il numero di utenti prima di quello corrente, ho completato la risposta con questa alternativa. –
il Q (profile__points__gt = point) | Q (profile__points = points) può essere cambiato in Q (profile__points_gte = point) giusto? –