ranklist相关的改动
This commit is contained in:
25
account/migrations/0003_userprofile_total_score.py
Normal file
25
account/migrations/0003_userprofile_total_score.py
Normal 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',
|
||||
),
|
||||
]
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"),
|
||||
]
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user