Caching and refactors
This commit is contained in:
parent
67b06d7856
commit
8f1c8d6c96
33 changed files with 485 additions and 381 deletions
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue