Move dirty logic to admin
This commit is contained in:
parent
e1a38d42c3
commit
11bc57f2b1
4 changed files with 38 additions and 31 deletions
|
@ -33,6 +33,7 @@ from judge.widgets import (
|
||||||
CheckboxSelectMultipleWithSelectAll,
|
CheckboxSelectMultipleWithSelectAll,
|
||||||
HeavyPreviewAdminPageDownWidget,
|
HeavyPreviewAdminPageDownWidget,
|
||||||
)
|
)
|
||||||
|
from judge.utils.problems import user_editable_ids, user_tester_ids
|
||||||
|
|
||||||
MEMORY_UNITS = (("KB", "KB"), ("MB", "MB"))
|
MEMORY_UNITS = (("KB", "KB"), ("MB", "MB"))
|
||||||
|
|
||||||
|
@ -359,12 +360,31 @@ class ProblemAdmin(CompareVersionAdmin):
|
||||||
self._rescore(request, obj.id)
|
self._rescore(request, obj.id)
|
||||||
|
|
||||||
def save_related(self, request, form, formsets, change):
|
def save_related(self, request, form, formsets, change):
|
||||||
|
editors = set()
|
||||||
|
testers = set()
|
||||||
|
if "curators" in form.changed_data or "authors" in form.changed_data:
|
||||||
|
editors = set(form.instance.editor_ids)
|
||||||
|
if "testers" in form.changed_data:
|
||||||
|
testers = set(form.instance.tester_ids)
|
||||||
|
|
||||||
super().save_related(request, form, formsets, change)
|
super().save_related(request, form, formsets, change)
|
||||||
# Only rescored if we did not already do so in `save_model`
|
|
||||||
obj = form.instance
|
obj = form.instance
|
||||||
obj.curators.add(request.profile)
|
obj.curators.add(request.profile)
|
||||||
obj.is_organization_private = obj.organizations.count() > 0
|
obj.is_organization_private = obj.organizations.count() > 0
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
||||||
|
if "curators" in form.changed_data or "authors" in form.changed_data:
|
||||||
|
del obj.editor_ids
|
||||||
|
editors = editors.union(set(obj.editor_ids))
|
||||||
|
if "testers" in form.changed_data:
|
||||||
|
del obj.tester_ids
|
||||||
|
testers = testers.union(set(obj.tester_ids))
|
||||||
|
|
||||||
|
for editor in editors:
|
||||||
|
user_editable_ids.dirty(editor)
|
||||||
|
for tester in testers:
|
||||||
|
user_tester_ids.dirty(tester)
|
||||||
|
|
||||||
# Create notification
|
# Create notification
|
||||||
if "is_public" in form.changed_data or "organizations" in form.changed_data:
|
if "is_public" in form.changed_data or "organizations" in form.changed_data:
|
||||||
users = set(obj.authors.all())
|
users = set(obj.authors.all())
|
||||||
|
|
|
@ -40,12 +40,10 @@ def cache_wrapper(prefix, timeout=None):
|
||||||
def _get(key):
|
def _get(key):
|
||||||
if not l0_cache:
|
if not l0_cache:
|
||||||
return cache.get(key)
|
return cache.get(key)
|
||||||
print("GET", key, l0_cache.get(key))
|
|
||||||
return l0_cache.get(key) or cache.get(key)
|
return l0_cache.get(key) or cache.get(key)
|
||||||
|
|
||||||
def _set_l0(key, value):
|
def _set_l0(key, value):
|
||||||
if l0_cache:
|
if l0_cache:
|
||||||
print("SET", key, value)
|
|
||||||
l0_cache.set(key, value, 30)
|
l0_cache.set(key, value, 30)
|
||||||
|
|
||||||
def _set(key, value, timeout):
|
def _set(key, value, timeout):
|
||||||
|
|
|
@ -436,15 +436,23 @@ class Problem(models.Model, PageVotable, Bookmarkable):
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def author_ids(self):
|
def author_ids(self):
|
||||||
return self.authors.values_list("id", flat=True)
|
return Problem.authors.through.objects.filter(problem=self).values_list(
|
||||||
|
"profile_id", flat=True
|
||||||
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def editor_ids(self):
|
def editor_ids(self):
|
||||||
return self.author_ids | self.curators.values_list("id", flat=True)
|
return self.author_ids.union(
|
||||||
|
Problem.curators.through.objects.filter(problem=self).values_list(
|
||||||
|
"profile_id", flat=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def tester_ids(self):
|
def tester_ids(self):
|
||||||
return self.testers.values_list("id", flat=True)
|
return Problem.testers.through.objects.filter(problem=self).values_list(
|
||||||
|
"profile_id", flat=True
|
||||||
|
)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def usable_common_names(self):
|
def usable_common_names(self):
|
||||||
|
|
|
@ -10,8 +10,6 @@ from django.db.models import Case, Count, ExpressionWrapper, F, Max, Q, When
|
||||||
from django.db.models.fields import FloatField
|
from django.db.models.fields import FloatField
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext as _, gettext_noop
|
from django.utils.translation import gettext as _, gettext_noop
|
||||||
from django.db.models.signals import pre_save
|
|
||||||
from django.dispatch import receiver
|
|
||||||
|
|
||||||
from judge.models import Problem, Submission
|
from judge.models import Problem, Submission
|
||||||
from judge.ml.collab_filter import CollabFilter
|
from judge.ml.collab_filter import CollabFilter
|
||||||
|
@ -29,9 +27,9 @@ __all__ = [
|
||||||
@cache_wrapper(prefix="user_tester")
|
@cache_wrapper(prefix="user_tester")
|
||||||
def user_tester_ids(profile):
|
def user_tester_ids(profile):
|
||||||
return set(
|
return set(
|
||||||
Problem.testers.through.objects.filter(profile=profile).values_list(
|
Problem.testers.through.objects.filter(profile=profile)
|
||||||
"problem_id", flat=True
|
.values_list("problem_id", flat=True)
|
||||||
)
|
.distinct()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +39,9 @@ def user_editable_ids(profile):
|
||||||
(
|
(
|
||||||
Problem.objects.filter(authors=profile)
|
Problem.objects.filter(authors=profile)
|
||||||
| Problem.objects.filter(curators=profile)
|
| Problem.objects.filter(curators=profile)
|
||||||
).values_list("id", flat=True)
|
)
|
||||||
|
.values_list("id", flat=True)
|
||||||
|
.distinct()
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -249,22 +249,3 @@ def finished_submission(sub):
|
||||||
keys += ["contest_complete:%d" % participation.id]
|
keys += ["contest_complete:%d" % participation.id]
|
||||||
keys += ["contest_attempted:%d" % participation.id]
|
keys += ["contest_attempted:%d" % participation.id]
|
||||||
cache.delete_many(keys)
|
cache.delete_many(keys)
|
||||||
|
|
||||||
|
|
||||||
@receiver([pre_save], sender=Problem)
|
|
||||||
def on_problem_save(sender, instance, **kwargs):
|
|
||||||
if instance.id is None:
|
|
||||||
return
|
|
||||||
prev_editors = list(sender.objects.get(id=instance.id).editor_ids)
|
|
||||||
new_editors = list(instance.editor_ids)
|
|
||||||
if prev_editors != new_editors:
|
|
||||||
all_editors = set(prev_editors + new_editors)
|
|
||||||
for profile_id in all_editors:
|
|
||||||
user_editable_ids.dirty(profile_id)
|
|
||||||
|
|
||||||
prev_testers = list(sender.objects.get(id=instance.id).tester_ids)
|
|
||||||
new_testers = list(instance.tester_ids)
|
|
||||||
if prev_testers != new_testers:
|
|
||||||
all_testers = set(prev_testers + new_testers)
|
|
||||||
for profile_id in all_testers:
|
|
||||||
user_tester_ids.dirty(profile_id)
|
|
||||||
|
|
Loading…
Reference in a new issue