Home > front end >  Django filter where model doesn't have a foreign object or foreign field is equal to
Django filter where model doesn't have a foreign object or foreign field is equal to

Time:03-08

I have two models Community and UserCommunity

Community Model

class Community(models.Model):

    # Community name
    name = models.CharField(max_length=64)
    slug = models.CharField(max_length=40, blank=True)
    admins = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name="admins", blank=True
    )
    admins = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name="admins", blank=True
    )
    members = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name="members",
        blank=True,
    )
    ------

UserCommunityModel

class UserCommunity(models.Model):

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=CASCADE, related_name="user"
    )
    group = models.ForeignKey(
        Community, on_delete=CASCADE, related_name="group")
    role = models.CharField(max_length=15, blank=True, null=True)
    # True is in community, false is not in community
    active = models.BooleanField(null=True, blank=True)

I need to get all the community objects where a user is not part of the community and the community should have at least 1 member

I've tried using this

Community.objects.filter(group__user=request.user.id, group__active=False,state=location.state, group_discoverability="public").exclude(
        hofAdmins__isnull=True, admins__isnull=True, members__isnull=True)[:10]

But this returns the communities which has a UserCommunity object, UserCommunity object is created when user joins the community. Any help would be appreciated, thanks!

CodePudding user response:

You can work with:

Community.objects.exclude(
    group__user=request.user,
    group__active=True
).exclude(
    mebers=request.user
).exclude(
    admins=request.user
)

This will thus exclude a Community from the moment there is a UserCommunity with active=True, and user=request.user.

or when the community should have at least one member:

Community.objects.filter(
    group__active=True
).exclude(
    group__user=request.user,
    group__active=True
).exclude(
    mebers=request.user
).exclude(
    admins=request.user
).distinct()

I would also advise to remove the many ManyToManyFields: your UserCommunity already is the junction table [wiki] between the user model and the Community. You can add a field role for example to disambiguate between members and admins. By making multiple many-to-many tables, the query will be less efficient and annotating will be more cumbersome.


Note: The related_name=… parameter [Django-doc] is the name of the relation in reverse, so from the User model to the Community model in this case. Therefore it (often) makes not much sense to name it the same as the forward relation. You thus might want to consider renaming the admins relation to admin_communities.

CodePudding user response:

Community.objects.filter(~Q(members__in=[request.user.id]), ~Q(hofAdmins__in=[request.user.id]), ~Q(admins__in=[request.user.id]), state=location.state, group_discoverability="public").exclude(         hofAdmins__isnull=True, admins__isnull=True, members__isnull=True)[:10]
  • Related