mirror of
https://github.com/DMOJ/online-judge.git
synced 2024-11-25 16:32:37 +08:00
Improve APIv2
- Sort all list endpoints by ID, which reduces the likelihood of objects moving between pages during requests. Objects will only shift if an object is deleted, which usually does not happen. - Add a list filter for ID (and other identifier fields), so users can request a list of only the objects they care about (rather than requesting all and then filtering on their side) - Use the rating from Profile.rating instead of re-computing it each time. This attribute should already be updated during each contest rate.
This commit is contained in:
parent
2035e606f3
commit
6baf5c3149
@ -199,6 +199,7 @@ class APIContestList(APIListView):
|
||||
('is_rated', 'is_rated'),
|
||||
)
|
||||
list_filters = (
|
||||
('key', 'key'),
|
||||
('tag', 'tags__name'),
|
||||
('organization', 'organizations'),
|
||||
)
|
||||
@ -213,7 +214,7 @@ class APIContestList(APIListView):
|
||||
to_attr='tag_list',
|
||||
),
|
||||
)
|
||||
.order_by('end_time')
|
||||
.order_by('id')
|
||||
)
|
||||
|
||||
def get_object_data(self, contest):
|
||||
@ -393,6 +394,7 @@ class APIProblemList(APIListView):
|
||||
('partial', 'partial'),
|
||||
)
|
||||
list_filters = (
|
||||
('code', 'code'),
|
||||
('group', 'group__full_name'),
|
||||
('type', 'types__full_name'),
|
||||
('organization', 'organizations'),
|
||||
@ -409,7 +411,7 @@ class APIProblemList(APIListView):
|
||||
to_attr='type_list',
|
||||
),
|
||||
)
|
||||
.order_by('code')
|
||||
.order_by('id')
|
||||
.distinct()
|
||||
)
|
||||
|
||||
@ -478,20 +480,18 @@ class APIProblemDetail(APIDetailView):
|
||||
class APIUserList(APIListView):
|
||||
model = Profile
|
||||
list_filters = (
|
||||
('id', 'id'),
|
||||
('username', 'username'),
|
||||
('organization', 'organizations'),
|
||||
)
|
||||
|
||||
def get_unfiltered_queryset(self):
|
||||
latest_rating_subquery = Rating.objects.filter(user=OuterRef('pk')).order_by('-contest__end_time')
|
||||
return (
|
||||
Profile.objects
|
||||
.filter(is_unlisted=False, user__is_active=True)
|
||||
.annotate(
|
||||
username=F('user__username'),
|
||||
latest_rating=Subquery(latest_rating_subquery.values('rating')[:1]),
|
||||
)
|
||||
.annotate(username=F('user__username'))
|
||||
.order_by('id')
|
||||
.only('id', 'points', 'performance_points', 'problem_count', 'display_rank')
|
||||
.only('id', 'points', 'performance_points', 'problem_count', 'display_rank', 'rating')
|
||||
)
|
||||
|
||||
def get_object_data(self, profile):
|
||||
@ -502,7 +502,7 @@ class APIUserList(APIListView):
|
||||
'performance_points': profile.performance_points,
|
||||
'problem_count': profile.problem_count,
|
||||
'rank': profile.display_rank,
|
||||
'rating': profile.latest_rating,
|
||||
'rating': profile.rating,
|
||||
}
|
||||
|
||||
|
||||
@ -524,8 +524,6 @@ class APIUserDetail(APIDetailView):
|
||||
.values_list('problem__code', flat=True),
|
||||
)
|
||||
|
||||
last_rating = profile.ratings.order_by('-contest__end_time').first()
|
||||
|
||||
contest_history = []
|
||||
participations = (
|
||||
ContestParticipation.objects
|
||||
@ -557,7 +555,7 @@ class APIUserDetail(APIDetailView):
|
||||
'problem_count': profile.problem_count,
|
||||
'solved_problems': solved_problems,
|
||||
'rank': profile.display_rank,
|
||||
'rating': last_rating.rating if last_rating is not None else None,
|
||||
'rating': profile.rating,
|
||||
'organizations': list(profile.organizations.values_list('id', flat=True)),
|
||||
'contests': contest_history,
|
||||
}
|
||||
@ -570,6 +568,7 @@ class APISubmissionList(APIListView):
|
||||
('problem', ProblemSimpleFilter('problem')),
|
||||
)
|
||||
list_filters = (
|
||||
('id', 'id'),
|
||||
('language', LanguageListFilter('language')),
|
||||
('result', 'result'),
|
||||
)
|
||||
@ -681,6 +680,9 @@ class APIOrganizationList(APIListView):
|
||||
basic_filters = (
|
||||
('is_open', 'is_open'),
|
||||
)
|
||||
list_filters = (
|
||||
('id', 'id'),
|
||||
)
|
||||
|
||||
def get_unfiltered_queryset(self):
|
||||
return Organization.objects.annotate(member_count=Count('member')).order_by('id')
|
||||
@ -700,6 +702,10 @@ class APILanguageList(APIListView):
|
||||
basic_filters = (
|
||||
('common_name', 'common_name'),
|
||||
)
|
||||
list_filters = (
|
||||
('id', 'id'),
|
||||
('key', 'key'),
|
||||
)
|
||||
|
||||
def get_object_data(self, language):
|
||||
return {
|
||||
@ -717,7 +723,7 @@ class APIJudgeList(APIListView):
|
||||
model = Judge
|
||||
|
||||
def get_unfiltered_queryset(self):
|
||||
return Judge.objects.filter(online=True).prefetch_related('runtimes').order_by('name')
|
||||
return Judge.objects.filter(online=True).prefetch_related('runtimes').order_by('id')
|
||||
|
||||
def get_object_data(self, judge):
|
||||
return {
|
||||
|
Loading…
Reference in New Issue
Block a user