【问题标题】:How to use filtering data while using distinct method in django?在 django 中使用 distinct 方法时如何使用过滤数据?
【发布时间】:2020-01-16 12:32:42
【问题描述】:

请帮助我解决我的问题我希望我的标题足以理解我的意思,请帮助我解决这个问题。

当我尝试这个时:

id_list = grade.objects.filter(Teacher=m.id).values_list('Students_Enrollment_Records_id',flat=True).distinct()

我使用distinct()从查询结果中消除重复的学生注册记录行,但我想知道为什么结果是这样的:

我应该怎么做才能在我的 html 中显示学生名称而不是 QuerySet?

这是我目前的views.py

id_list = grade.objects.filter(Teacher=m.id).values_list('Students_Enrollment_Records_id',flat=True).distinct()
print(id_list)
grades = grade.objects.filter(Students_Enrollment_Records_id__in=id_list)
print(grades)

这是我的 models.py

class grade(models.Model):
    Teacher = models.ForeignKey(EmployeeUser, related_name='+', on_delete=models.CASCADE,
                                null=True, blank=True)
    Grading_Categories = models.ForeignKey(gradingCategories, related_name='+', on_delete=models.CASCADE,
                                           null=True, blank=True)
    Subjects = models.ForeignKey(Subject, related_name='+', on_delete=models.CASCADE, null=True)
    Students_Enrollment_Records = models.ForeignKey(StudentsEnrolledSubject, related_name='+',
                                                    on_delete=models.CASCADE, null=True)
    Average = models.FloatField(null=True, blank=True)

更新

当我尝试这个时

piste = grade.objects.filter(Teacher_id=m.id).values_list('Students_Enrollment_Records').annotate(Average=Avg('Average')).order_by('Grading_Categories').distinct()

计算是固定的,但没有显示教师姓名,学科和学生姓名,但显示ID是这样的

这是我想要的答案

这就是我在 html 中发布的方式

views.py

return render(request, 'Homepage/index.html', {"piste":piste})

html

{% for n in piste %}
          <tr>
              <td>{{n.Teacher}}</td>
              <td>{{n.Subjects}}</td>
              <td>{{n.Students_Enrollment_Records.Students_Enrollment_Records.Student_Users}}</td>
              <td>{{n}}</td>
          </tr>
          {% endfor %}

这是model.py

class EmployeeUser(models.Model):
    Image = models.ImageField(upload_to='images', null=True, blank=True)
    Employee_Number = models.CharField(max_length=500, null=True)
    Username = models.CharField(max_length=500, null=True)
    Password = models.CharField(max_length=500, null=True)
    My_Department = models.ForeignKey(Department, related_name='+', on_delete=models.CASCADE, blank=True)
    My_Position = models.ForeignKey(Position, related_name='+', on_delete=models.CASCADE, blank=True)
    Firstname = models.CharField(max_length=500, null=True)
    Middle_Initial = models.CharField(max_length=500, null=True)
    Lastname = models.CharField(max_length=500, null=True)
    Educational_Attainment = models.ForeignKey(EducationalAttainment, related_name='+', on_delete=models.CASCADE,
                                               null=True)
    Landline = models.CharField(max_length=500, null=True)
    Mobile_Number = models.CharField(max_length=500, null=True)
    Email = models.CharField(max_length=500, null=True)
    Facebook_Acoount = models.CharField(max_length=500, null=True)

    Fathers_Firstname = models.CharField(max_length=500, null=True)
    Fathers_Middle_Initial = models.CharField(max_length=500, null=True)
    Fathers_Lastname = models.CharField(max_length=500, )
    Educational_Attainment_Father = models.ForeignKey(EducationalAttainment, related_name='+', on_delete=models.CASCADE,
                                                      null=True)
    Father_Occupation = models.CharField(max_length=500, null=True)
    Father_Company_Employed = models.CharField(max_length=500, null=True)
    Father_Landline = models.CharField(max_length=500, null=True)
    Father_MobileNo = models.CharField(max_length=500, null=True)
    Father_Email = models.CharField(max_length=500, null=True)
    Father_Facebook_Account = models.CharField(max_length=500, null=True)

    Mother_FirstName = models.CharField(max_length=500, null=True)
    Mother_Middle_Initial = models.CharField(max_length=500, null=True)
    Mother_Maiden_LastName = models.CharField(max_length=500, null=True)
    Educational_AttainmentID_Mother = models.ForeignKey(EducationalAttainment, related_name='+',
                                                        on_delete=models.CASCADE, null=True)
    Mother_Occupation = models.CharField(max_length=500, null=True)
    Mother_Company_Employed = models.CharField(max_length=500, null=True)
    Mother_Landline = models.CharField(max_length=500, null=True)
    Mother_MobileNo = models.CharField(max_length=500, null=True)
    Mother_Email = models.CharField(max_length=500, null=True)
    Mother_Facebook_Account = models.CharField(max_length=500, null=True)
    Family_Status = models.ForeignKey(FamilyStatu, related_name='+', on_delete=models.CASCADE, null=True)
    Country = models.CharField(max_length=500, null=True)
    ZIP_Postal_Code = models.CharField(max_length=500, null=True)
    State_Province = models.CharField(max_length=500, null=True)
    City = models.CharField(max_length=500, null=True)
    Barangay = models.CharField(max_length=500, null=True)
    Unit_Number_Street = models.CharField(max_length=500, null=True)
    LandMark = models.CharField(max_length=500, null=True)
    AddressLine1 = models.CharField(max_length=500, null=True)
    AddressLine2 = models.CharField(max_length=500, null=True)
    AddressLine3 = models.CharField(max_length=500, null=True)

    def __str__(self):
        suser = '{0.Firstname}   {0.Middle_Initial}      {0.Lastname}'
        return suser.format(self)

class StudentsEnrolledSubject(models.Model):
    Students_Enrollment_Records = models.ForeignKey(StudentsEnrollmentRecord, related_name='+',
                                                    on_delete=models.CASCADE, null=True)
    Subject_Section_Teacher = models.ForeignKey(SubjectSectionTeacher, related_name='+', on_delete=models.CASCADE,
                                                null=True)

这是完整的视图.py

m = EmployeeUser.objects.get(Username=request.POST['p_user'], Password = request.POST['p_pass'], My_Position =request.POST['position'])
piste = grade.objects.all().filter(Teacher=m.id).values_list('Students_Enrollment_Records').annotate(Average=Avg('Average')).order_by('Grading_Categories').distinct()
return render(request, 'Homepage/index.html', {"piste":piste})

更新

当我尝试@nigel222 先生的这个答案时

piste = grade.objects.filter(Teacher=m.id).annotate(grade_average=Avg('Average')).order_by('Grading_Categories').distinct()

到我的html

{% for n in piste %}
      <tr>
          <td>{{n.Teacher}}</td> <!-- 1 -->
          <td>{{n.Subjects}}</td> <!-- 2 -->
          <td>{{n.Students_Enrollment_Records.Students_Enrollment_Records.Student_Users}}
               </td>  <!-- 3 -->
          <td>{{n}}</td>  <!--4 -->
      </tr>
      {% endfor %}

我得到了这个结果

【问题讨论】:

  • 与问题无关,但您似乎发布了整个 EmployeeUser 模型,它缺少使用散列机制设置和检查密码的方法。它是否存在于其他地方,或者您是否以明文形式存储密码?
  • 我以明文形式存储密码 mr @schillingt
  • 请,请,请不要那样做。而是扩展 Django 的内置用户和/或 BaseAbstractUser:docs.djangoproject.com/en/3.0/topics/auth/customizing/…
  • 好吧,@schillingt 先生,下次请你帮我解决我的问题好吗?差不多 3-4 天我不知道如何解决这个问题
  • 我不明白你要渲染什么。

标签: python django django-views


【解决方案1】:

我已经有几年没有和 Django 一起工作了,但这就是我认为正在发生的事情。

您正在将 values_list(一个元组)分配给 piste。您没有将 grade 对象分配给 piste。但是,在您的模板中,您希望 piste 的元素是成绩。

我认为您需要先获取grade 对象并将其发送到模板以及piste

【讨论】:

    【解决方案2】:

    您不想要values_list(这是您在第 4 列中获得的数据)。你想要一个 grade 对象的查询集:

    piste = grade.objects.filter(Teacher_id=m.id
            ).annotate(Average=Avg('Average')
            ).order_by('Grading_Categories'
            ).distinct()
    

    然后在你的模板中,类似

    {% for n in piste %}
          <tr>
              <td>{{n.Teacher}}</td> <!-- 1 -->
              <td>{{n.Subjects}}</td> <!-- 2 -->
              <td>{{n.Students_Enrollment_Records.Students_Enrollment_Records.Student_Users}}
                   </td>  <!-- 3 -->
              <td>{{n}}</td>  <!--4 -->
          </tr>
          {% endfor %}
    

    1 和 2 渲染 EmployeeUserSubject 对象。 1 将返回EmployeeUser__str__ 表示,这应该没问题。或者,您可以在模板中明确使用 {{n.Teacher.FirstName}} 等。

    3 我不明白,因为您没有显示 Students_Enrolled_Subject 模型。

    4 现在是错误的。也许你想要注解{{n.Average}}

    请尽快学习使用 Django/Python 编码约定。 Model 子类(以及一般的 Python 类名)以大写字母开头。类的实例是小写的。字段名/属性通常是小写字母,并且绝对以小写字母开头。模型子类名称是单数名称而不是复数名称。不这样做对于任何有经验的 Django 编码器来说都是非常混乱的。所以,

    class Grade(models.Model):
        teacher = models.ForeignKey(EmployeeUser, related_name='+', on_delete=models.CASCADE,
                                null=True, blank=True)
        grading_categories = models.ForeignKey(GradingCategory, related_name='+', on_delete=models.CASCADE,
                                           null=True, blank=True)
        subject = models.ForeignKey(Subject, related_name='+', on_delete=models.CASCADE, null=True)
        students_enrollment_records = models.ForeignKey(StudentsEnrolledSubject, related_name='+',
                                                    on_delete=models.CASCADE, null=True)
    

    【讨论】:

    • 我会试试这个先生,请稍候
    • 当我复制你的答案先生时,我遇到了这个错误“”“注释'平均值'与模型上的字段冲突。”“”
    • 确实如此。注释是您动态添加到模型中的东西。更改字段或注释的名称。
    • 先生,我添加了 StudentsEnrolledSubject,请查看
    • 我应该在您的答案中更改什么以更正此错误 ""注释 'Average' 与模型上的字段冲突。""
    【解决方案3】:

    这是我能为你做的最好的。我认为您应该根据学生来选择并过滤给老师的成绩。我还对所有主题进行了预取,因为我不太清楚你需要在那里做什么。

    students = Student.objects.filter(
        grades__teacher_id=teacher.id,
    ).annotate(
        total_avg=Avg('grades__Average')
    ).prefetch_related('grades__Subjects')
    

    模板:

    {% for student in students %}
          <tr>
              <td>{{teacher}}</td>
              <td>{{student.grades.subjects.all}}</td>
              <td>{{student}}</td>
              <td>{{student.total_avg}}</td>
          </tr>
    {% endfor %}
    

    【讨论】:

    • 'QuerySet' 对象没有属性 'id' 我遇到这个错误
    猜你喜欢
    • 2022-06-24
    • 2020-06-24
    • 2013-08-19
    • 2021-04-10
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多