2013-04-21 12 views

risposta

3

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.

+0

che dovrebbe funzionare. Qualche idea su come posso ottenere la "posizione" degli utenti in quell'ordine? –

+0

@ Nuno_147 È possibile contare il numero di utenti prima di quello corrente, ho completato la risposta con questa alternativa. –

+0

il Q (profile__points__gt = point) | Q (profile__points = points) può essere cambiato in Q (profile__points_gte = point) giusto? –

1

io sono sicuro che cosa i vostri punti sono, ma questo dovrebbe essere solo annotare, qualcosa di simile al di sotto ...

from django.db.models import Sum, Avg 

UserProfile.objects.annotate(sum_rating=Sum('sum__points')).order_by('-sum_points') 

Non dimenticate che è possibile utilizzare la variabile di annotazione in un filtro.

Aggiornamento: giusto ordine per punti, notare che il -

UserProfile.objects.filter(whatever here).order_by('-points')[:5] 

o

.order_by('points')[:5] 
+0

Mi spiace di non averlo specificato, ma non ho bisogno di annotazioni perché i miei punti sono già calcolati e sono punti non elaborati. la sfida qui è come devo ottenere il + 5-5 di alcuni punti utente. Voglio la sua posizione nella classifica e in aggiunta il 5 prima di lui e il 5 dopo di lui. –

+0

Quindi filtrare per punti e ordinare per. È quindi possibile ottenere solo i primi 5 di questi risultati. Per gli ultimi cinque farlo in ordine decrescente. –

+0

la mia domanda proveniva da un utente specifico non dall'alto. Devo localizzare l'utente nell'ordine e ottenere il +5 -5. –

Problemi correlati