diff --git a/core/auth/mixins.py b/core/auth/mixins.py index b8d8ee10..28012d50 100644 --- a/core/auth/mixins.py +++ b/core/auth/mixins.py @@ -307,6 +307,7 @@ class PermissionOrClubBoardRequiredMixin(PermissionRequiredMixin): return False if super().has_permission(): return True - return self.club is not None and any( - g.id == self.club.board_group_id for g in self.request.user.all_groups + return ( + self.club is not None + and self.club.board_group_id in self.request.user.all_groups ) diff --git a/core/models.py b/core/models.py index a5ae84a3..3b533751 100644 --- a/core/models.py +++ b/core/models.py @@ -356,10 +356,10 @@ class User(AbstractUser): ) if group_id is None: return False - return any(g.id == group_id for g in self.all_groups) + return group_id in self.all_groups @cached_property - def all_groups(self) -> list[Group]: + def all_groups(self) -> dict[int, Group]: """Get the list of groups this user is in.""" additional_groups = [] if self.is_subscribed: @@ -372,14 +372,11 @@ class User(AbstractUser): # a UNION rather than a OR (in average, 0.25ms vs 14ms). # For the why, cf. https://dba.stackexchange.com/questions/293836/why-is-an-or-statement-slower-than-union qs = qs.union(Group.objects.filter(id__in=additional_groups)) - return list(qs) + return {g.id: g for g in qs} @cached_property def is_root(self) -> bool: - if self.is_superuser: - return True - root_id = settings.SITH_GROUP_ROOT_ID - return any(g.id == root_id for g in self.all_groups) + return self.is_superuser or settings.SITH_GROUP_ROOT_ID in self.all_groups @cached_property def is_board_member(self) -> bool: @@ -1106,8 +1103,7 @@ class PageQuerySet(models.QuerySet): return self.filter(view_groups=settings.SITH_GROUP_PUBLIC_ID) if user.has_perm("core.view_page"): return self.all() - groups_ids = [g.id for g in user.all_groups] - return self.filter(view_groups__in=groups_ids) + return self.filter(view_groups__in=user.all_groups) # This function prevents generating migration upon settings change @@ -1381,7 +1377,7 @@ class PageRev(models.Model): return self.page.can_be_edited_by(user) def is_owned_by(self, user: User) -> bool: - return any(g.id == self.page.owner_group_id for g in user.all_groups) + return self.page.owner_group_id in user.all_groups def similarity_ratio(self, text: str) -> float: """Similarity ratio between this revision's content and the given text. diff --git a/election/views.py b/election/views.py index 1f67ec0d..63cd70d9 100644 --- a/election/views.py +++ b/election/views.py @@ -115,7 +115,7 @@ class VoteFormView(LoginRequiredMixin, UserPassesTestMixin, FormView): if not self.election.can_vote(self.request.user): return False return self.election.vote_groups.filter( - id__in=[g.id for g in self.request.user.all_groups] + id__in=self.request.user.all_groups ).exists() def vote(self, election_data): @@ -231,7 +231,7 @@ class RoleCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView): if self.request.user.has_perm("election.add_role"): return True return self.election.edit_groups.filter( - id__in=[g.id for g in self.request.user.all_groups] + id__in=self.request.user.all_groups ).exists() def get_initial(self): @@ -265,7 +265,7 @@ class ElectionListCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView .union(self.election.edit_groups.values("id")) .values_list("id", flat=True) ) - return not groups.isdisjoint({g.id for g in self.request.user.all_groups}) + return not groups.isdisjoint(self.request.user.all_groups.keys()) def get_initial(self): return {"election": self.election}