2013-04-21 32 views
5

Tôi có một mô hình cho mọi người dùng trên trang web của mình (UserProfile) mỗi cấu hình chứa một trường có tên là các điểm.Triển khai bảng thành tích bằng cách sử dụng Django

Tôi muốn nhận được -5 +5 người dùng từ người dùng hiện tại trong khi sắp xếp theo điểm. Làm thế nào tôi có thể thực hiện điều này?

Trả lời

3

Bạn có thể làm hai truy vấn, một cho người dùng trước khi người sử dụng hiện tại, và một cho người dùng chỉ sau:

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] 

Đây là căn cứ trên hai truy vấn:

  • Tất cả người dùng với điểm số lớn hơn người dùng hiện tại hoặc có cùng số điểm nhưng với điểm số thấp hơn pk.
  • Tất cả người dùng có điểm số thấp hơn người dùng hiện tại hoặc có cùng số điểm nhưng với số điểm cao hơn pk.

Sau đó, với thứ tự và giới hạn thích hợp, bạn có thể nhận được kết quả của mình. Tất nhiên pk có thể được thay thế bằng bất kỳ ứng dụng nào khác, hoặc chỉ được xóa hoàn toàn. Trong trường hợp sau, bạn thay vì có thể xem xét mà người dùng hiện tại luôn là đầu tiên (đây chỉ là một ví dụ), và các truy vấn trở thành:

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] 

Ngoài ra, để có được chỉ là chỉ số của người dùng hiện trong danh sách của người sử dụng sắp xếp theo điểm, bạn có thể làm:

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() 

Sau đó, danh sách người dùng tập trung vào hiện tại sẽ chỉ là:

User.objects.all().order_by('-profile__points', 'pk')[index - 5:index + 6] 

thay thế này có thể chậm hơn nếu bạn có nhiều người dùng, vì toàn bộ danh sách người dùng trước khi người dùng hiện tại cần được đánh giá, nhưng tôi đã không xác minh điều này.

+0

Điều đó sẽ làm việc. bất kỳ ý tưởng làm thế nào tôi có thể nhận được "vị trí" của người dùng theo thứ tự đó? –

+0

@ Nuno_147 Bạn có thể đếm số lượng người dùng trước một người hiện tại, tôi đã hoàn thành câu trả lời của mình với giải pháp thay thế này. –

+0

Q (profile__points__gt = point) | Q (profile__points = points) có thể được thay đổi thành Q (profile__points_gte = point) phải không? –

1

tôi không chắc chắn những gì điểm của bạn nhưng điều này chỉ nên được chú thích, một cái gì đó như dưới đây ...

from django.db.models import Sum, Avg 

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

Đừng quên bạn có thể sử dụng biến chú thích trong một bộ lọc.

Cập nhật: chỉ để bằng điểm, lưu ý các -

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

hoặc

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

Xin lỗi tôi đã không nói rằng, Nhưng tôi không cần chú thích vì điểm của tôi được tính toán allready và là điểm thô. thách thức ở đây là làm thế nào tôi nên nhận được + 5-5 của một số điểm người dùng. Tôi muốn vị trí của anh ta trong ban lãnh đạo và bổ sung 5 trước anh ta và 5 sau anh ta. –

+0

Sau đó lọc theo điểm và thứ tự theo. Sau đó, bạn có thể nhận được 5 kết quả hàng đầu. Trong năm người cuối cùng làm theo thứ tự giảm dần. –

+0

câu hỏi của tôi là từ một người dùng cụ thể không phải từ trên cùng. Tôi cần tìm người dùng theo thứ tự và nhận được +5 -5. –

Các vấn đề liên quan