Django фильтр, в котором модель не имеет внешнего объекта или внешнее поле равно
У меня есть две модели Community и UserCommunity
Модель сообщества
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)
Мне нужно получить все объекты сообщества, в которых пользователь не является членом сообщества
Я пробовал использовать это
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]
Но это возвращает сообщества, которые имеют объект UserCommunity, объект UserCommunity создается, когда пользователь присоединяется к сообществу. Любая помощь будет принята с благодарностью, спасибо!
Вы можете работать с:
Community.objects.exclude(
group__user=request.user,
group__active=True
).exclude(
mebers=request.user
).exclude(
admins=request.user
)
Таким образом, Community будет исключать с момента появления UserCommunity с active=True, и user=request.user.
или когда в сообществе должен быть хотя бы один участник:
Community.objects.filter(
group__active=True
).exclude(
group__user=request.user,
group__active=True
).exclude(
mebers=request.user
).exclude(
admins=request.user
).distinct()
Я бы также посоветовал убрать множество ManyToManyField: ваша UserCommunity уже является таблицей [wiki] между моделью пользователя и Community. Вы можете добавить поле role, например, для разграничения между членами и администраторами. Если сделать несколько таблиц типа "многие ко многим", запрос будет менее эффективным, а аннотирование будет более громоздким.
Примечание: Параметр
.related_name=…[Django-doc] является именем отношения в reverse, поэтому от моделиUserк моделиCommunityв данном случае. Поэтому (часто) не имеет особого смысла называть его тем же именем, что и прямое отношение. так же, как и прямое отношение. Таким образом, вы можете рассмотреть возможность переименования отношениявadminsadmin_communities.
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]