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 <anders@zulip.com>
This commit is contained in:
Sahil Batra 2021-10-11 12:07:15 +05:30 committed by Tim Abbott
parent 40470b938b
commit 6ac9386a29
4 changed files with 50 additions and 8 deletions

View File

@ -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

View File

@ -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:

View File

@ -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,
),
),
]

View File

@ -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"),)