如何查询以便显示每个实例的字段而不是实际实例

How to query so that a field of each instance will show up instead of the actual instance

我正在尝试查询,以便每个模型实例中的字段值都不会重复显示。所有这一切都发生在表格中:

class OrganisorClassStatusUpdateForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(OrganisorClassStatusUpdateForm, self).__init__(*args, **kwargs)
        self.fields['off_day_student'] = forms.ModelChoiceField(
            queryset= Class.objects.filter(teacher=self.instance.teacher).filter(is_new_set=True).filter(time=self.instance.time).order_by('-date')[:10]
        )

此处,self.instance 指的是我正在使用此表单更新的 Class 模型实例。但是,使用此代码,我会收到一个表单字段的 Class 实例列表。我想要的是一个 Student 的列表,对应于表单字段中的每个 Class 个实例(每个 class 只有一个学生)。因此,我想要 Student1、Student2、Student3,而不是 Class1、Class2、Class3。此外,如果学生姓名有任何重复,我想只显示一个。希望同学们如上代码所示,classes也按照-date的顺序列出。请问我任何问题。非常感谢。

这里是 Class 一些人问过的模型:

class Class(models.Model):
    teacher = models.ForeignKey('Agent', null=True, blank=True, on_delete=models.SET_NULL)
    student = models.ForeignKey('Lead', null=True, blank=True, on_delete=models.SET_NULL, related_name='student')

如果教师是 Class 模型中的字段,您可以说:

ids = Class.objects.filter(student=self.object.student).order_by('-date').values_list("teacher", flat=True).distinct()[:10] 
queryset = Teacher.objects.filter(pk__in=ids)

这是 Queryset.values() 的文档:https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.values 请注意:将 values() 与 distinct() 一起使用时,请注意排序会影响结果。有关详细信息,请参阅 distinct() 中的注释。 (来自文档) 似乎有办法解决这个问题。请阅读本文档页面中的注释部分:https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.distinct

您可以使用:

Teacher.objects.filter(
    <strong>class__student=self.instance.student</strong>,
    class__is_new_set=True,
    class__time=self.instance.time,
).order_by('-class__date').distinct()[:10]

如果你定义一个从ClassTeacher的关系,那么Django会反向添加一个概念关系。您可以使用 related_query_name=… [Django-doc] or the related_name=… parameter [Django-doc] 指定该关系的名称。默认情况下,related_query_name 字段是 class 的小写名称。

如果您只想一次检索每个 Teacher 对象,则不能 .order_by('-class__date'),因为那样会执行没有 [=18= 的 JOIN ] 条款。

在这种情况下,您可以订购最小的 class__date,例如:

from django.db.models import Min

Teacher.objects.filter(
    class__student=self.instance.student,
    class__is_new_set=True,
    class__time=self.instance.time,
)<strong>.alias(</strong>
    min_date=Min('class_date')
<strong>)</strong>.order_by(<strong>'-min_date'</strong>).distinct()[:10]

或在 之前:

from django.db.models import Min

Teacher.objects.filter(
    class__student=self.instance.student,
    class__is_new_set=True,
    class__time=self.instance.time,
)<strong>.annotate(</strong>
    min_date=Min('class__date')
<strong>)</strong>.order_by(<strong>'-min_date'</strong>).distinct()[:10]

或者如果你想要学生:

from django.db.models import Min

Student.objects.filter(
    student__student=self.instance.student,
    student__is_new_set=True,
    student__time=self.instance.time,
)<strong>.annotate(</strong>
    min_date=Min('student__date')
<strong>)</strong>.order_by(<strong>'-min_date'</strong>).distinct()[:10]

我们在这里使用student__的原因是因为related_name='student'在你从ClassLead的关系中。然而,这没有多大意义。与以下人员合作可能会更好:

class Class(models.Model):
    teacher = models.ForeignKey('Agent', null=True, blank=True, on_delete=models.SET_NULL)
    student = models.ForeignKey('Lead', null=True, blank=True, on_delete=models.SET_NULL<strong>, related_name='classes'</strong>)

然后查询:

from django.db.models import Min

Student.objects.filter(
    <strong>classes__</strong>student=self.instance.student,
    <strong>classes__</strong>student__is_new_set=True,
    <strong>classes__</strong>student__time=self.instance.time,
).annotate(
    min_date=Min('<strong>classes__</strong>date')
).order_by('-min_date').distinct()[:10]