Reputation: 409
I have the following setup. I have Teachers, which can have many Students. Both of them are Django Users. Students can leave reviews for Teachers. I'm building the Teacher Detail View. That is the url /teachers/1
where /teachers/
is the List View.
Now the problem:
I want all reviews, left by the user to be visible in the given teacher view. That would correspond to a 'ListView' within a DetailedView. Urls.py
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.TeacherView.as_view(), name='detail'),
]
Models.py
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='Teacher')
availability = models.BooleanField(default=False)
def __str__(self):
return self.user.username
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='Student')
teacher = models.OneToOneField(Teacher, on_delete=models.PROTECT, related_name='Student')
reviewed = models.BooleanField(default=False)
def __str__(self):
return self.user.username
class Review(models.Model):
teacher = models.OneToOneField(Teacher, on_delete=models.PROTECT, related_name='Teacher')
student = models.OneToOneField(Student, on_delete=models.PROTECT, related_name='Student')
star = models.IntegerField(default=5)
body = models.TextField()
And finally the main problem - views.py
class IndexView(ListView):
# context_object_name = 'latest_teacher_list'
def get_queryset(self):
"""Return the last five published questions."""
return Teacher.objects.all()[:5]
class TeacherView(generic.DetailView):
model = Teacher
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(TeacherView, self).get_context_data(**kwargs)
# Add extra context from another model
context['reviews'] = Review.objects.filter(teacher_pk=pk)
return context
This doesn't work, it complains that pk is not defined. What it does in my head, is get the pk from URL, then finds all review objects where user.teacher.pk (or teacher.pk or teacher_pk) = pk.
I tried playing around with **kwags and replacing by pk, without success.
Also, as additional question I would like to display the average rating.
I'm thinking of rating = Review.objects.filter(teacher_pk=pk).aggregate(Avg('star')
Upvotes: 2
Views: 926
Reputation: 308899
You can get the pk from self.kwargs
:
context['reviews'] = Review.objects.filter(teacher_pk=self.kwargs['pk'])
Upvotes: 3