1

I am learning Django by building an example app in which I have student users who can sign up for Study sections. For each student user I have a ListView which creates a table list of all of the relevant study sections for them. Each Study model is related to a Detail model which contains the details of the study section such as location and start time. For each Study I would like to add values of the associated Detail such as location and start time, but I am having trouble figuring out how to pass this information into the template from the 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>

This current try yields the error:

Exception Value: 'RelatedManager' object has no attribute 'details'
1
  • Your get_object returns a collection of Studys, not a single one, so accessing .details makes no sense. Commented Jan 6, 2019 at 16:40

1 Answer 1

2

Django ORM doesn't create a Study.details property. To access all related Detail objects, you should write Study.detail_set. Furthermore, Study.get_details is a method, so it shouldn't accept a second argument – it just makes no sense. Together, this means your code should look like this:

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

Also, your code seems chaotic, let me know if you have more issues.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi mgradowski, thank you for your answer. Indeed, this is my first Django app, so I am still figuring out how to write things efficiently. How do I use this function to pass the details of each study into the template through the view? When I try to call it in get_context_data I keep getting errors such as 'RelatedManager' object has no attribute 'get_details'
@Ambrose Can you provide full error message? Right now I am not able to determine the exact reason you keep getting this error.
I figured it out! I called it in the template instead as study.get_details. Thanks for your help @mgradowski

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.