diff --git a/account/views/admin.py b/account/views/admin.py index 83f4a93e..94af4b9f 100644 --- a/account/views/admin.py +++ b/account/views/admin.py @@ -21,22 +21,10 @@ class UserAdminAPI(APIView): user = User.objects.get(id=data["id"]) except User.DoesNotExist: return self.error("User does not exist") - try: - user = User.objects.get(username=data["username"]) - if user.id != data["id"]: - return self.error("Username already exists") - except User.DoesNotExist: - pass - - try: - user = User.objects.get(email=data["email"]) - if user.id != data["id"]: - return self.error("Email already exists") - # Some old data has duplicate email - except MultipleObjectsReturned: + if User.objects.filter(username=data["username"]).exclude(id=user.id).exists(): + return self.error("Username already exists") + if User.objects.filter(email=data["email"].lower()).exclude(id=user.id).exists(): return self.error("Email already exists") - except User.DoesNotExist: - pass user.username = data["username"] user.email = data["email"] diff --git a/announcement/views/admin.py b/announcement/views/admin.py index 86d54303..58d35780 100644 --- a/announcement/views/admin.py +++ b/announcement/views/admin.py @@ -28,13 +28,12 @@ class AnnouncementAdminAPI(APIView): """ data = request.data try: - announcement = Announcement.objects.get(id=data["id"]) + announcement = Announcement.objects.get(id=data.pop("id")) except Announcement.DoesNotExist: return self.error("Announcement does not exist") - announcement.title = data["title"] - announcement.content = data["content"] - announcement.visible = data["visible"] + for k, v in data.items(): + setattr(announcement, k, v) announcement.save() return self.success(AnnouncementSerializer(announcement).data) diff --git a/problem/views/admin.py b/problem/views/admin.py index 7d1ac676..a7e24db9 100644 --- a/problem/views/admin.py +++ b/problem/views/admin.py @@ -8,7 +8,7 @@ from django.conf import settings from account.decorators import problem_permission_required from contest.models import Contest from utils.api import APIView, CSRFExemptAPIView, validate_serializer -from utils.shortcuts import rand_str +from utils.shortcuts import rand_str, natural_sort_key from ..models import Problem, ProblemRuleType, ProblemTag from ..serializers import (CreateContestProblemSerializer, ContestProblemAdminSerializer, @@ -30,7 +30,7 @@ class TestCaseUploadAPI(CSRFExemptAPIView): prefix += 1 continue else: - return sorted(ret) + return sorted(ret, key=natural_sort_key) else: while True: in_name = str(prefix) + ".in" @@ -41,7 +41,7 @@ class TestCaseUploadAPI(CSRFExemptAPIView): prefix += 1 continue else: - return sorted(ret) + return sorted(ret, key=natural_sort_key) @problem_permission_required def post(self, request): diff --git a/utils/shortcuts.py b/utils/shortcuts.py index 8fc1ffac..9340564e 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -1,3 +1,4 @@ +import re import datetime import random from base64 import b64encode @@ -57,3 +58,8 @@ def datetime2str(value, format="iso-8601"): def timestamp2utcstr(value): return datetime.datetime.utcfromtimestamp(value).isoformat() + + +def natural_sort_key(s, _nsre=re.compile(r"(\d+)")): + return [int(text) if text.isdigit() else text.lower() + for text in re.split(_nsre, s)]