From 6ac9386a294e24750c17ab23e1fab21298fe01f4 Mon Sep 17 00:00:00 2001 From: Sahil Batra Date: Mon, 11 Oct 2021 12:07:15 +0530 Subject: [PATCH] models: Add related_name to UserGroup and UserGroupMembership fields. This commit adds related_name parameter to UserGroup.direct_members such that we can use direct_groups instead of the default usergroupmembership_set for getting all the groups of which the user is direct member. This commit also sets related_name of UserGroupMembership.user_group and UserGroupMembership.user_profile to "+" which means that we will not be having backward relations for these. This change is correct since we would need to use the recursive queries to get all the groups of a user and all the members of a group after we add the subgroups concept in next commit. This leads to us using direct_members field of UserGroup instead of usergroupmembership_set in mention code, but this will soon be replaced with the recursive query function to include subgroup's members as well. Extracted this commit from #19866. Authored-by : Anders Kaseorg --- zerver/lib/mention.py | 6 +-- zerver/lib/user_groups.py | 2 +- .../0365_alter_user_group_related_fields.py | 42 +++++++++++++++++++ zerver/models.py | 8 ++-- 4 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 zerver/migrations/0365_alter_user_group_related_fields.py diff --git a/zerver/lib/mention.py b/zerver/lib/mention.py index e4dbbe82e8..b85b6d0f33 100644 --- a/zerver/lib/mention.py +++ b/zerver/lib/mention.py @@ -102,11 +102,9 @@ class MentionData: if user_group_names: for group in UserGroup.objects.filter( realm_id=realm_id, name__in=user_group_names, is_system_group=False - ).prefetch_related("usergroupmembership_set"): + ).prefetch_related("direct_members"): self.user_group_name_info[group.name.lower()] = group - self.user_group_members[group.id] = [ - m.user_profile_id for m in group.usergroupmembership_set.all() - ] + self.user_group_members[group.id] = [m.id for m in group.direct_members.all()] def get_user_by_name(self, name: str) -> Optional[FullNameInfo]: # warning: get_user_by_name is not dependable if two diff --git a/zerver/lib/user_groups.py b/zerver/lib/user_groups.py index 51bd7a1e62..26dec2b773 100644 --- a/zerver/lib/user_groups.py +++ b/zerver/lib/user_groups.py @@ -55,7 +55,7 @@ def user_groups_in_realm_serialized(realm: Realm) -> List[Dict[str, Any]]: def get_direct_user_groups(user_profile: UserProfile) -> List[UserGroup]: - return list(user_profile.usergroup_set.all()) + return list(user_profile.direct_groups.all()) def remove_user_from_user_group(user_profile: UserProfile, user_group: UserGroup) -> int: diff --git a/zerver/migrations/0365_alter_user_group_related_fields.py b/zerver/migrations/0365_alter_user_group_related_fields.py new file mode 100644 index 0000000000..225122c068 --- /dev/null +++ b/zerver/migrations/0365_alter_user_group_related_fields.py @@ -0,0 +1,42 @@ +# Generated by Django 3.2.7 on 2021-10-10 10:13 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("zerver", "0364_rename_members_usergroup_direct_members"), + ] + + operations = [ + migrations.AlterField( + model_name="usergroup", + name="direct_members", + field=models.ManyToManyField( + related_name="direct_groups", + through="zerver.UserGroupMembership", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AlterField( + model_name="usergroupmembership", + name="user_group", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="zerver.usergroup", + ), + ), + migrations.AlterField( + model_name="usergroupmembership", + name="user_profile", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/zerver/models.py b/zerver/models.py index ec7dc7473a..a4fef62328 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -1978,7 +1978,9 @@ class PasswordTooWeakError(Exception): class UserGroup(models.Model): id: int = models.AutoField(auto_created=True, primary_key=True, verbose_name="ID") name: str = models.CharField(max_length=100) - direct_members: Manager = models.ManyToManyField(UserProfile, through="UserGroupMembership") + direct_members: Manager = models.ManyToManyField( + UserProfile, through="UserGroupMembership", related_name="direct_groups" + ) realm: Realm = models.ForeignKey(Realm, on_delete=CASCADE) description: str = models.TextField(default="") is_system_group: bool = models.BooleanField(default=False) @@ -1989,8 +1991,8 @@ class UserGroup(models.Model): class UserGroupMembership(models.Model): id: int = models.AutoField(auto_created=True, primary_key=True, verbose_name="ID") - user_group: UserGroup = models.ForeignKey(UserGroup, on_delete=CASCADE) - user_profile: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE) + user_group: UserGroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+") + user_profile: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE, related_name="+") class Meta: unique_together = (("user_group", "user_profile"),)