用户过滤多对多关系并在模板Django中显示

时间:2017-11-09 07:36:35

标签: python django templates model m2m

我遇到了问题。我正在开发电子学习应用程序并拥有此模型(为了更好地理解而简化):

class Course(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=255)
    enrolled = models.ManyToManyField(get_user_model(), through='Enrol', related_name="course_enrolled")
    teacher = models.ForeignKey(get_user_model(), on_delete=models.CASCADE,
                                related_name="course_teacher")


class Section(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=255)
    course = models.ForeignKey(Course, on_delete=models.CASCADE)


class Classe(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=255)
    content = models.TextField()
    section = models.ForeignKey(Section, on_delete=models.CASCADE)
    completed = models.ManyToManyField(get_user_model(), through='ClassCompleted', related_name="classes_completed")


class Enrol(models.Model):
    student = models.ForeignKey(get_user_model())
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)


class ClassCompleted(models.Model):
    student = models.ForeignKey(get_user_model())
    classe = models.ForeignKey(Classe, on_delete=models.CASCADE)
    completed = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)

我的课程页面视图。此页面必须显示章节和类。

@login_required
def ead_course(request, course_id):
    try:
         course = Course.objects.get(id=course_id)
    except Course.DoesNotExist:
         raise Http404

     # Check if student is enroll or is a teacher
    if request.user.course_enrolled.filter(id=course_id).exists() or course.teacher.id is request.user.id:
        return render(request, 'ead/ead_course.html', {'course': course})

    return HttpResponse("Without permission")

最后我的模板ead_course.html:

{% for section in course.section_set.all %}
    {{ section.name }}
    {% for class in section.classe_set.all %}
        {{ class.name }}
    {% endfor %}
{% endfor %}

到目前为止,一切都很好,我会向用户展示所有部分和课程。

最大的问题是:我需要检查一个学生是否完成了一些课程,所以我创建了一个多对多的表ClassCompleted,以向学生展示他的进度,但是我很难在模板。

我需要按部分分隔进度,因此每个部分将显示学生完成的课程数量。像这样:

第1单元 - 完成2/4课程

  • 第1类(已完成)
  • 第2类(已完成)
  • 第3类
  • 第4类

第2单元 - 0/1完成课程

  • 第1类

我通过在视图中创建过滤器并创建模板标记来尝试此操作,但没有成功。

2 个答案:

答案 0 :(得分:0)

我认为您需要过滤用户完成的所有课程,并在forloop中与所有课程进行互动

@login_required
def ead_course(request, course_id):
     try:
         course = Course.objects.get(id=course_id)
     except Course.DoesNotExist:
         raise Http404

     # Check if student is enroll or is a teacher
     if request.user.course_enrolled.filter(id=course_id).exists() or course.teacher.id is request.user.id:
          courses_completed = ClassCompleted.objects.filter(student=request.user, completed=True)
          return render(request, 'ead/ead_course.html', {'course': course, 'courses_completed': courses_completed})

    return HttpResponse("Without permission")

并在模板中:

{% for section in course.section_set.all %}
    {{ section.name }}
    {% for class in section.classe_set.all %}
        {{ class.name }}
        {% for completed in courses_completed %}
            {% if class.id == completed.classe.id %}
            <p>Completou</p>
            {% endif %}
        {% endfor %}
    {% endfor %}
{% endfor %}

答案 1 :(得分:0)

我可以通过过滤器模板标签来实现这一点,过滤模板标签按部分和用户过滤已完成的类。我不知道这是否是最好的做法,但有效!

from django import template

from ..models import ClassCompleted

register = template.Library()

@register.filter
def completed_class_for_section_for_user(section, user):
    return ClassCompleted.objects.filter(classe__section=section, student=user, completed=True)

在模板中使用:

{% for section in course.section_set.all %}
    {{ section.name }}
    {% for classe in section.classe_set.all %}
        {{ classe.name }}
        {% for completed_classe in section|completed_class_for_section_for_user:user %}
            {% if completed_classe.classe.id == classe.id %}
                Completed                
            {% endif %}
        {% endfor %}
    {% endfor %}
{% endfor %}

如果有人有更好的解决方案,请在此处发帖。