获取外部对象而不是 ID 列表的 QuerySet

Posted

技术标签:

【中文标题】获取外部对象而不是 ID 列表的 QuerySet【英文标题】:Get Foreign Objects instead of QuerySet of List of ID's 【发布时间】:2020-11-28 17:31:43 【问题描述】:

单行代码即可获取外键对象,而不是 UUID 的 QuerySet。

我有三个模型,

Student, College, Member

模型的定义类似于下面

class Student(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name=models.CharField(max_length=128)

class College(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name=models.CharField(max_length=128)

class Member(models.Model):
    student= models.ForeignKey(Student, related_name="students", on_delete=models.CASCADE)
    college= models.ForeignKey(College, related_name="colleges", on_delete=models.CASCADE)

其中 Member 包含 Student 和 College 作为外键字段

现在我想根据应从 Member 模型中过滤掉的 college_id 获取属于特定学院的所有学生

我现在过得怎么样

student_ids = Member.objects.filter(college_id=college_id).values("student")

现在students 是学生 UUID 列表的查询集

因为我需要实际的学生对象而不是 UUID 的 QuerySet 列表

students = Student.objects.filter(id__in=[str(uid) for uid in student_ids])

我觉得这是一种不恰当的方式。任何人都可以建议一行代码来获取外键对象而不是 UUID 的 QuerySet。提前致谢

【问题讨论】:

【参考方案1】:

你可以过滤:

Student.objects.filter(<b>students__college_id=<i>college_id</i></b>)

related_name=… parameter [Django-doc] 然而是 reverse 中关系的名称。因此,将它们重命名为更有意义,例如:

class Member(models.Model):
    student = models.ForeignKey(
        Student,
        related_name='members',
        on_delete=models.CASCADE
    )
    college = models.ForeignKey(
        College,
        related_name='members',
        on_delete=models.CASCADE
    )

然后你过滤:

Student.objects.filter(<b>members__college_id=<i>college_id</i></b>)

您还可以在CollegeStudent 之间跨越一个概念 ManyToManyField [Django-doc]:

class Student(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=128)
    colleges = models.ManyToManyField(
        'College',
        related_name='students'
        through='Member'
    )

然后你可以过滤:

Student.objects.filter(<b>colleges=<i>college_id</i></b>)

【讨论】:

以上是关于获取外部对象而不是 ID 列表的 QuerySet的主要内容,如果未能解决你的问题,请参考以下文章

查询集 QuerySet

django queryset“包含”列表,而不是字符串

findById 返回文档列表而不是单个结果

Django查询集QuerySet及两大特性

QuerySet,对象没有属性 id - Django

django queryset 返回“类名对象”而不是 DB 值