ranklist相关的改动

This commit is contained in:
zemal
2017-08-20 20:32:07 +08:00
parent 3b1f02c356
commit 07643e2639
6 changed files with 97 additions and 24 deletions

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2017-08-20 02:03
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('account', '0002_auto_20170209_1028'),
]
operations = [
migrations.AddField(
model_name='userprofile',
name='total_score',
field=models.BigIntegerField(default=0),
),
migrations.RenameField(
model_name='userprofile',
old_name='accepted_problem_number',
new_name='accepted_number',
),
]

View File

@@ -69,28 +69,38 @@ def _random_avatar():
class UserProfile(models.Model):
user = models.OneToOneField(User)
# Store user problem solution status with json string format
# {"problems": {1: JudgeStatus.ACCEPTED}, "contest_problems": {20: JudgeStatus.PENDING)}
# Store user problem solution status with json string format, Only for problems not contest_problems
# ACM: {1: {status: JudgeStatus.ACCEPTED}}
# OI: {1: {score: 33}}
problems_status = JSONField(default={})
avatar = models.CharField(max_length=50, default=_random_avatar)
blog = models.URLField(blank=True, null=True)
mood = models.CharField(max_length=200, blank=True, null=True)
accepted_problem_number = models.IntegerField(default=0)
submission_number = models.IntegerField(default=0)
phone_number = models.CharField(max_length=15, blank=True, null=True)
school = models.CharField(max_length=200, blank=True, null=True)
major = models.CharField(max_length=200, blank=True, null=True)
student_id = models.CharField(max_length=15, blank=True, null=True)
time_zone = models.CharField(max_length=32, blank=True, null=True)
language = models.CharField(max_length=32, blank=True, null=True)
# for ACM
accepted_number = models.IntegerField(default=0)
# for OI
total_score = models.BigIntegerField(default=0)
submission_number = models.IntegerField(default=0)
def add_accepted_problem_number(self):
self.accepted_problem_number = models.F("accepted_problem_number") + 1
self.accepted_number = models.F("accepted_number") + 1
self.save()
def add_submission_number(self):
self.submission_number = models.F("submission_number") + 1
self.save()
# 计算总分时, 应先减掉上次该题所得分数, 然后再加上本次所得分数
def add_score(self, this_time_score, last_time_score=None):
last_time_score = last_time_score or 0
self.total_score = models.F("total_score") - last_time_score + this_time_score
self.save()
class Meta:
db_table = "user_profile"

View File

@@ -1,6 +1,6 @@
from django import forms
from utils.api import DateTimeTZField, serializers
from utils.api import DateTimeTZField, serializers, UsernameSerializer
from .models import AdminType, ProblemPermission, User, UserProfile
@@ -97,3 +97,10 @@ class TwoFactorAuthCodeSerializer(serializers.Serializer):
class AvatarUploadForm(forms.Form):
file = forms.FileField()
class RankInfoSerializer(serializers.ModelSerializer):
user = UsernameSerializer()
class Meta:
model = UserProfile

View File

@@ -3,7 +3,8 @@ from django.conf.urls import url
from ..views.oj import (ApplyResetPasswordAPI, ResetPasswordAPI,
UserChangePasswordAPI, UserRegisterAPI,
UserLoginAPI, UserLogoutAPI, UsernameOrEmailCheck,
SSOAPI, AvatarUploadAPI, TwoFactorAuthAPI, UserProfileAPI)
SSOAPI, AvatarUploadAPI, TwoFactorAuthAPI, UserProfileAPI,
UserRankAPI)
from utils.captcha.views import CaptchaAPIView
@@ -19,5 +20,6 @@ urlpatterns = [
url(r"^profile/?$", UserProfileAPI.as_view(), name="user_profile_api"),
url(r"^avatar/upload/?$", AvatarUploadAPI.as_view(), name="avatar_upload_api"),
url(r"^sso/?$", SSOAPI.as_view(), name="sso_api"),
url(r"^two_factor_auth/?$", TwoFactorAuthAPI.as_view(), name="two_factor_auth_api")
url(r"^two_factor_auth/?$", TwoFactorAuthAPI.as_view(), name="two_factor_auth_api"),
url(r"^user_rank/?$", UserRankAPI.as_view(), name="user_rank_api"),
]

View File

@@ -18,10 +18,10 @@ from utils.shortcuts import rand_str
from ..decorators import login_required
from ..models import User, UserProfile
from ..serializers import (ApplyResetPasswordSerializer,
ResetPasswordSerializer,
from ..serializers import (ApplyResetPasswordSerializer, ResetPasswordSerializer,
UserChangePasswordSerializer, UserLoginSerializer,
UserRegisterSerializer, UsernameOrEmailCheckSerializer)
UserRegisterSerializer, UsernameOrEmailCheckSerializer,
RankInfoSerializer)
from ..serializers import (SSOSerializer, TwoFactorAuthCodeSerializer,
UserProfileSerializer,
EditUserProfileSerializer, AvatarUploadForm)
@@ -32,6 +32,7 @@ class UserProfileAPI(APIView):
"""
判断是否登录, 若登录返回用户信息
"""
@method_decorator(ensure_csrf_cookie)
def get(self, request, **kwargs):
user = request.user
@@ -321,3 +322,16 @@ class ResetPasswordAPI(APIView):
user.set_password(data["password"])
user.save()
return self.success("Succeeded")
class UserRankAPI(APIView):
def get(self, request):
rule_type = request.GET.get("rule")
if rule_type not in ["acm", "oi"]:
rule_type = "acm"
profiles = UserProfile.objects.select_related("user").filter(submission_number__gt=0)
if rule_type == "acm":
profiles = profiles.order_by("-accepted_number", "submission_number")
else:
profiles = profiles.order_by("-total_score")
return self.success(self.paginate_data(request, profiles, RankInfoSerializer))