I am making a website that allows students to find upcoming study sessions for their courses. I am doing this in Django and HTML. A student uploads their courses to the site and they are shown on the courses page as buttons (ex. CS 101 - Intro to CS). When a student clicks on one of their courses (button), it is supposed to bring them to a page that shows available study sessions for that course. I am stuck because I do not know how to properly filter the available study sessions on the next page based on which course is clicked. Is there a way to store the info of the course as a variable so when the button is clicked I can use that variable to filter the results? EDIT: I have made these changes and now I am getting a ValueError too many values to unpack expected 2. I am almost certain it is happening in my views.
Here is the page that shows a user's courses
<div style="top:50%; bottom:50%; width:100%;">
<div >
{% if courses_list %}
{% for course in courses_list %}
<a type="button" href="{% url 'study:course-session'%}" >{{ course.subject }} {{ course.number}}-{{course.name}} </a>
<br><br><br>
{% endfor %}
{% else %}
<p >You have not added any courses yet!</p>
{% endif %}
</div>
</div>
And here is the page that I am trying to filter the list of study sessions (which have a field course that is a ForeignKey to the Courses model):
<h1><center>Upcoming Study Sessions</center></h1>
<div>
<a style="position:absolute; margin-right:2px; top:15%; right:0;" href="{% url 'study:courses' %}" role="button" >Back to My Courses</a>
</div>
<br><br>
<div style="top:50%; bottom:50%; width:100%;">
<div >
<button type="button" >Date/Time: {{ session.date }} <br> Location: {{ session.location }} </button>
<br><br><br>
</div>
</div>
View for the template:
def CourseSessionView(request, course_pk):
course_wanted = Course.objects.get(id=course_pk)
try:
return Study.objects.filter(course=course_wanted)
except:
return messages.error(request, 'There are no upcoming study sessions at this time for the requested course.')
Model for course and session:
class Course(models.Model):
SUBJECT_CHOICES = [
('AAS', 'AAS')
]
subject = models.CharField(
max_length=4, choices=SUBJECT_CHOICES, default='')
number = models.PositiveSmallIntegerField(
validators=[MaxValueValidator(9999)], default=0)
name = models.CharField(max_length=100, default='')
roster = models.ManyToManyField(
Student, blank=True, related_name="courses")
# Use [Student object].courses.all() to see all of a student's courses
def __str__(self):
return f"{self.subject} {self.number} - {self.name}"
class Study(models.Model):
organizer = models.ForeignKey(Student, on_delete=models.CASCADE)
date = models.DateTimeField()
# Use [Student object].studies.all() to see all of a student's study sessions
attendees = models.ManyToManyField(Student, related_name="studies")
location = models.CharField(max_length=30)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def __str__(self):
return f"{self.date} - {self.location}"
Url:
path('<int:course_pk>/sessions/',
views.CourseSessionView, name='course-session')
CodePudding user response:
This is going to be a very general type of answer since you are not providing your models or your views, but I think the idea would be the following.
First, in your template you can pass a parameter for the course number in the url:
your_template.html
<a type="button"
href="{% url 'study:course-session' course.pk %}">
{{ course.subject }} {{ course.number}}-{{course.name}}
</a>
Then in your view you can access that value, and from it get the course:
views.py
def the_view_name(request, course_pk):
# Here you now have access to the course's primary key, pk, so you can get the
# course and filter the study sessions by that course, etc...
You will need to modify the urls.py so the view can accept this new parameter:
urls.py
path('the_view_name/<int:course_pk>', views.the_view_name, name='the_view_name'),
CodePudding user response:
Note:
The function based views' name doesn't require to be inPascalCase
as in your case, it should be insnake_case
.
The page that show the user's courses, there you need to pk
of courses:
<div style="top:50%; bottom:50%; width:100%;">
<div >
{% if courses_list %}
{% for course in courses_list %}
<a type="button" href="{% url 'study:course-session' course.pk %}" >{{ course.subject }} {{ course.number}}-{{course.name}} </a>
<br><br><br>
{% endfor %}
{% else %}
<p >You have not added any courses yet!</p>
{% endif %}
</div>
</div>
Your view for the template, i am defining it in snake_case
, since its recommended way.
def course_session(request, course_pk):
course_wanted = Course.objects.get(id=course_pk)
study_courses=''
try:
study_courses= Study.objects.filter(course=course_wanted)
except:
messages.error(request, 'There are no upcoming study sessions at this time for the requested course.')
else:
return render(request,'anyfolder/anyfile.html',{'study_courses':study_courses})
return render(request,'anyfolder/anyfile.html') #then it will show only your error message.
Your url
in urls.py be like:
path('any_route_name/<int:course_pk>/', views.course_session, name='course_session')
Note:
Never forget to pass/
at the end of yoururl
orroute_name
.
Then, in your any template
file you can access it and run loop:
{% for study in study_courses %}
{{study.organizer}},{{study.date}}
{% endfor %}
Then, you can access all its properties, and take benefit of ManyToOne
relation.