Как использовать значения и distinct для разных полей в Django ORM?
В настоящее время у меня есть термины в моих приложениях, и у одного пользователя может быть зарегистрировано много терминов, и моя текущая модель выглядит следующим образом
class Term(models.Model):
id = models.UUIDField("id", default=uuid.uuid4, editable=False, primary_key=True)
user_id = models.PositiveIntegerField("user id", default=None)
name = models.CharField()
<
Term.objects.filter(active=True)
.order_by("user_id")
.values("user_id")
.distinct()
и этого достаточно, чтобы решить мои проблемы, но теперь я изменю свою модель и она будет выглядеть так:
class Term(models.Model):
id = models.UUIDField("id", default=uuid.uuid4, editable=False, primary_key=True)
user_id = models.PositiveIntegerField("user id", default=None)
name = models.CharField()
shared_with = ArrayField(models.PositiveIntegerField("id do usuario"), blank=True) # New
Как вы можете видеть, я добавил новое поле shared_with, которое в основном представляет собой массив идентификаторов пользователей, с которыми я хочу поделиться терминами, поэтому теперь мне нужно сделать запрос, который вернет все идентификаторы, которые могут иметь зарегистрированные термины (включая shared_with). Так что если я зарегистрирую термин с user_id = 1 и shared_with = [2,3], мой запрос должен вернуть [1,2,3].
< users = set()
for user in (
Term.objects.filter(active=True)
.order_by("user_id")
.values("user_id")
.distinct()
):
users.add(user["user_id"])
for user in (
Term.objects.filter(active=True)
.order_by("user_id")
.values("shared_with")
):
for user_id in user["shared_with"]:
users.add(user_id)
print(users) # {1,2,3}
<
Я не рекомендую использовать PositiveIntegerField
и ArrayField
в качестве отношений между таблицами, вместо этого вы можете использовать ForeignKey
и ManyToManyField
, в вашем случае, как я понимаю, у пользователя может быть много терминов, и один термин может быть общим для многих пользователей, поэтому идеальным решением будет добавить ManyToManyField
в вашу модель пользователя
class User(AbstarctUser):
... (your fields)
terms = models.ManyToManyField(Term, related_name="users")
и Term
модель будет выглядеть следующим образом:
class Term(models.Model):
id = models.UUIDField("id", default=uuid.uuid4, editable=False, primary_key=True)
name = models.CharField(max_length=200)
active = models.BooleanField(default=True)
... (other fields)
В этом случае, если вы хотите извлечь идентификаторы пользователей с активными терминами, вы можете получить их следующим образом :
users = User.objects.filter(terms__active=True).distinct().values_list("id", flat=True)