在ListView中注释QuerySet:Django

时间:2019-01-06 16:33:31

标签: python django

我正在通过构建一个示例应用程序来学习Django,在该应用程序中,我有一些学生用户可以注册“学习”部分。对于每个学生用户,我都有一个ListView,它为他们创建了所有相关学习部分的表格列表。每个研究模型都与一个详细模型相关,该模型包含研究部分的详细信息,例如位置和开始时间。对于每项研究,我都想添加相关明细的值,例如位置和开始时间,但是我在弄清楚如何将该信息从ListView传递到模板中时遇到麻烦。

models.py

class Study(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='studies')
    name = models.CharField(max_length=255)
    condition = models.ForeignKey(Condition, on_delete=models.CASCADE, related_name='studies')

    def get_details(self, study):
        details = study.details.all().order_by('start_date')
        return details

    def __str__(self):
        return self.name


class Detail(models.Model):
    study = models.ForeignKey(Study, on_delete=models.CASCADE, related_name='details')
    Location = models.CharField('Detail', max_length=255)
    start_date = models.DateField('event start date', default=datetime.date.today)
    end_date = models.DateField('event end date', default=datetime.date.today)
    start_time = models.TimeField('event start time', default=now)
    end_time = models.TimeField('event end time', default=now)
    description = models.TextField(blank=True)

    def __str__(self):
        return self.Location

views.py

@method_decorator([login_required, student_required], name='dispatch')
class StudyListView(ListView):
    model = Study
    ordering = ('name', )
    context_object_name = 'studies'
    template_name = 'classroom/students/study_list.html'

    def get_object(self):
        return self.request.user.studies

    def get_context_data(self, **kwargs):
        kwargs['details'] = self.get_object().details.annotate()
        return super().get_context_data(**kwargs)

    def get_queryset(self):
        student = self.request.user.student
        student_conditions = student.conditions.values_list('pk', flat=True)
        participating_studies = student.study_answers.filter(participate=True).values_list('study_id', flat=True)
        queryset = Study.objects.filter(condition__in=student_conditions) \
        .exclude(pk__in=participating_studies)
        return queryset

template.html

        {% for study,detail in zip(studies,details) %}
      <tr>
        <td class="align-middle">{{ study.name }}</td>
        <td class="align-middle">{{ study.condition.get_html_badge }}</td>
        <td class="align-middle">{{ detail.Location }} details</td>
        <td class="text-right">
          <a href="{% url 'students:past_study' study.pk %}" class="btn btn-primary">View Study</a>
        </td>
      </tr>

当前尝试会产生错误:

Exception Value: 'RelatedManager' object has no attribute 'details'

1 个答案:

答案 0 :(得分:1)

Django ORM不会创建Study.details属性。要访问所有相关的Detail对象,您应该编写Study.detail_set。此外,Study.get_details是一种方法,因此它不应该接受第二个参数–这毫无意义。 在一起,这意味着您的代码应如下所示:

def get_details(self):
    return self.detail_set.order_by('start_date').all()

此外,您的代码似乎很混乱,如果您还有其他问题,请告诉我。