传递几个参数来渲染模板

时间:2016-08-04 14:25:33

标签: python django

首先,请原谅我的英语 - 它不是我的母语。

我有以下模特:

class Student(models.Model):
    student_id = models.IntegerField(primary_key=True)
    student_name = models.CharField(max_length=255, default='John Doe')
    dob = models.DateField(max_length=8)

class Group(models.Model):
    group_name = models.CharField(max_length=40)
    monitor = models.ForeignKey(Student)

class Student_Group(models.Model):
    student_id = models.ForeignKey(Student)
    group_name = models.ForeignKey(Group)

我需要在每组中呈现学生群体,其监视器和学生数量。完成前两个任务不是问题:

views.py:

def group_list(request):
    groups = Group.objects.all()
    return render(request, 'groups/group_list.html', {'groups': groups})

groups.html

{% for group in groups %}
    <p>{{ group.group_name }}</p>
    <p>{{ group.monitor }}</p>
{% endfor %}

但是,当谈到为每个小组渲染学生数量时,我会陷入困境。

以下SQL可以计算给定组中的学生数量

select count(*) from students_student
join students_student_group
on students_student.student_id = students_student_group.student_id_id
where students_student_group.group_name_id = "Mega nerds"

问题是:

  1. 如何使用Django ORM获取每个小组的学生数量,因此该模板将呈现以下信息:

    • 团体名称:Mega nerds
    • 学生人数:8
    • 监视器:John Doe

    ...

    • 团体名称:好人
    • 学生人数:11
    • 监视器:John Appleseed
  2. 如何将有关学生数量的数据传递给相应的小组。
  3. 感谢。

    更新

    根据@Gocht的建议,我使用了ManyToManyField,所以我的models.py现在看起来像

    class Student(models.Model):
        student_id = models.IntegerField(primary_key=True)
        student_name = models.CharField(max_length=255, default='Василий Пупкин')
        dob = models.DateField(max_length=8)
    
        def __str__(self):
            return self.student_name
    
    
    class Group(models.Model):
        group_name = models.CharField(max_length=40, primary_key=True)
        monitor = models.ForeignKey(Student)
        students = models.ManyToManyField(Student, related_name='students')
    

    另外,正如建议的那样,我已将装饰器添加到Group类:

    @property
    def get_students_qty(self):
        return self.students.all().count()
    

    所以现在我可以得到每组中的学生人数,如下:

    {% for group in groups %}
        <p>{{ group.group_name }}</p>
        <p>{{ group.monitor }}</p>
        <p>{{ group.get_students_qty }}</p>
    {% endfor %}
    

    但我仍然想知道 - 是否有可能在不使用装饰者的情况下获得小组学生人数?毕竟,Group班级有students字段......

1 个答案:

答案 0 :(得分:1)

你可以得到这样一个群体中的学生人数:

group = ...  # get a group

n_students = Student_Group.objects.filter(group=group).count()

然后,由于每个Student_Group对象都有一个学生,n_students将包含给定组中的学生人数。

要将此号码发送到您的模板,您可以在上下文中添加:

def group_list(request):
    groups = Group.objects.all()
    return render(request, 'groups/group_list.html', {'groups': groups, 'n_students': n_students})

您还可以查看ManyToMany关系的文档,这可能会对您有所帮助。

修改

花点时间查看Python's naming conventions;您的Student_Group应为StudentGroup

您可以在模型中创建一个方法来返回组中学生的数量:

# models.py
class Group(models.Model):

    # fields

    @property
    def get_students_qty(self):
        return self.student_group_set.all().count()
        # Try with self.studentgroup_set.all().count() if the line
        # above does not work

然后在你的模板中:

{% for group in groups %}
    <p>{{ group.group_name }}</p>
    <p>{{ group.monitor }}</p>
    <p>{{ group.get_students_qty }}</p>
{% endfor %}