Как использовать значения и 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)
Вернуться на верх