Caching and refactors

This commit is contained in:
cuom1999 2024-04-13 17:02:54 -05:00
parent 67b06d7856
commit 8f1c8d6c96
33 changed files with 485 additions and 381 deletions

View file

@ -6,6 +6,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from judge.models.profile import Profile
from judge.caching import cache_wrapper
__all__ = ["BookMark"]
@ -21,12 +22,9 @@ class BookMark(models.Model):
object_id = models.PositiveIntegerField()
linked_object = GenericForeignKey("content_type", "object_id")
@cache_wrapper(prefix="BMgb")
def get_bookmark(self, user):
userqueryset = MakeBookMark.objects.filter(bookmark=self, user=user)
if userqueryset.exists():
return True
else:
return False
return MakeBookMark.objects.filter(bookmark=self, user=user).exists()
class Meta:
verbose_name = _("bookmark")
@ -55,11 +53,22 @@ class MakeBookMark(models.Model):
verbose_name_plural = _("make bookmarks")
@cache_wrapper(prefix="gocb")
def _get_or_create_bookmark(content_type, object_id):
bookmark, created = BookMark.objects.get_or_create(
content_type=content_type,
object_id=object_id,
)
return bookmark
class Bookmarkable:
def get_or_create_bookmark(self):
if self.bookmark.count():
return self.bookmark.first()
new_bookmark = BookMark()
new_bookmark.linked_object = self
new_bookmark.save()
return new_bookmark
content_type = ContentType.objects.get_for_model(self)
object_id = self.pk
return _get_or_create_bookmark(content_type, object_id)
def dirty_bookmark(bookmark, profile):
bookmark.get_bookmark.dirty(bookmark, profile)
_get_or_create_bookmark.dirty(bookmark.content_type, bookmark.object_id)

View file

@ -20,6 +20,7 @@ from judge.models.interface import BlogPost
from judge.models.problem import Problem, Solution
from judge.models.profile import Profile
from judge.utils.cachedict import CacheDict
from judge.caching import cache_wrapper
__all__ = ["Comment", "CommentLock", "CommentVote", "Notification"]
@ -75,16 +76,16 @@ class Comment(MPTTModel):
queryset = (
cls.objects.filter(hidden=False)
.select_related("author__user")
.defer("author__about", "body")
.defer("author__about")
.order_by("-id")
)
if organization:
queryset = queryset.filter(author__in=organization.members.all())
problem_access = CacheDict(lambda p: p.is_accessible_by(user))
object_access = CacheDict(lambda p: p.is_accessible_by(user))
contest_access = CacheDict(lambda c: c.is_accessible_by(user))
blog_access = CacheDict(lambda b: b.can_see(user))
blog_access = CacheDict(lambda b: b.is_accessible_by(user))
if n == -1:
n = len(queryset)
@ -174,3 +175,10 @@ class CommentLock(models.Model):
def __str__(self):
return str(self.page)
@cache_wrapper(prefix="gcc")
def get_visible_comment_count(content_type, object_id):
return Comment.objects.filter(
content_type=content_type, object_id=object_id, hidden=False
).count()

View file

@ -13,6 +13,7 @@ from mptt.models import MPTTModel
from judge.models.profile import Organization, Profile
from judge.models.pagevote import PageVotable
from judge.models.bookmark import Bookmarkable
from judge.caching import cache_wrapper
__all__ = ["MiscConfig", "validate_regex", "NavigationBar", "BlogPost"]
@ -105,7 +106,7 @@ class BlogPost(models.Model, PageVotable, Bookmarkable):
def get_absolute_url(self):
return reverse("blog_post", args=(self.id, self.slug))
def can_see(self, user):
def is_accessible_by(self, user):
if self.visible and self.publish_on <= timezone.now():
if not self.is_organization_private:
return True
@ -132,6 +133,10 @@ class BlogPost(models.Model, PageVotable, Bookmarkable):
and self.authors.filter(id=user.profile.id).exists()
)
@cache_wrapper(prefix="BPga")
def get_authors(self):
return self.authors.only("id")
class Meta:
permissions = (("edit_all_post", _("Edit all posts")),)
verbose_name = _("blog post")

View file

@ -31,11 +31,8 @@ class PageVote(models.Model):
@cache_wrapper(prefix="PVvs")
def vote_score(self, user):
page_vote = PageVoteVoter.objects.filter(pagevote=self, voter=user)
if page_vote.exists():
return page_vote.first().score
else:
return 0
page_vote = PageVoteVoter.objects.filter(pagevote=self, voter=user).first()
return page_vote.score if page_vote else 0
def __str__(self):
return f"pagevote for {self.linked_object}"
@ -52,11 +49,22 @@ class PageVoteVoter(models.Model):
verbose_name_plural = _("pagevote votes")
@cache_wrapper(prefix="gocp")
def _get_or_create_pagevote(content_type, object_id):
pagevote, created = PageVote.objects.get_or_create(
content_type=content_type,
object_id=object_id,
)
return pagevote
class PageVotable:
def get_or_create_pagevote(self):
if self.pagevote.count():
return self.pagevote.first()
new_pagevote = PageVote()
new_pagevote.linked_object = self
new_pagevote.save()
return new_pagevote
content_type = ContentType.objects.get_for_model(self)
object_id = self.pk
return _get_or_create_pagevote(content_type, object_id)
def dirty_pagevote(pagevote, profile):
pagevote.vote_score.dirty(pagevote, profile)
_get_or_create_pagevote.dirty(pagevote.content_type, pagevote.object_id)

View file

@ -24,6 +24,7 @@ from judge.models.problem_data import (
problem_data_storage,
problem_directory_file_helper,
)
from judge.caching import cache_wrapper
__all__ = [
"ProblemGroup",
@ -439,6 +440,10 @@ class Problem(models.Model, PageVotable, Bookmarkable):
"profile_id", flat=True
)
@cache_wrapper(prefix="Pga")
def get_authors(self):
return self.authors.only("id")
@cached_property
def editor_ids(self):
return self.author_ids.union(

View file

@ -141,6 +141,14 @@ class Organization(models.Model):
def get_submissions_url(self):
return reverse("organization_submissions", args=(self.id, self.slug))
@cache_wrapper("Oia")
def is_admin(self, profile):
return self.admins.filter(id=profile.id).exists()
@cache_wrapper("Oim")
def is_member(self, profile):
return profile in self
class Meta:
ordering = ["name"]
permissions = (
@ -280,6 +288,14 @@ class Profile(models.Model):
def is_muted(self):
return self._cached_info["mute"]
@cached_property
def cached_display_rank(self):
return self._cached_info.get("display_rank")
@cached_property
def cached_rating(self):
return self._cached_info.get("rating")
@cached_property
def profile_image_url(self):
return self._cached_info.get("profile_image_url")
@ -374,7 +390,7 @@ class Profile(models.Model):
@cached_property
def css_class(self):
return self.get_user_css_class(self.display_rank, self.rating)
return self.get_user_css_class(self.cached_display_rank, self.cached_rating)
def get_friends(self): # list of ids, including you
friend_obj = self.following_users.prefetch_related("users")
@ -388,11 +404,7 @@ class Profile(models.Model):
if not self.user.is_authenticated:
return False
profile_id = self.id
return (
org.admins.filter(id=profile_id).exists()
or org.registrant_id == profile_id
or self.user.is_superuser
)
return org.is_admin(self) or self.user.is_superuser
@classmethod
def prefetch_profile_cache(self, profile_ids):
@ -544,7 +556,7 @@ def on_profile_save(sender, instance, **kwargs):
_get_basic_info.dirty(instance.id)
@cache_wrapper(prefix="Pgbi2")
@cache_wrapper(prefix="Pgbi3")
def _get_basic_info(profile_id):
profile = (
Profile.objects.select_related("user")
@ -556,6 +568,8 @@ def _get_basic_info(profile_id):
"user__email",
"user__first_name",
"user__last_name",
"display_rank",
"rating",
)
.get(id=profile_id)
)
@ -569,6 +583,8 @@ def _get_basic_info(profile_id):
"profile_image_url": profile.profile_image.url
if profile.profile_image
else None,
"display_rank": profile.display_rank,
"rating": profile.rating,
}
res = {k: v for k, v in res.items() if v is not None}
return res