Enrolling in courses

After users create an account, they should be able to enroll in courses. In order to store enrollments, we need to create a many-to-many relationship between the Course and User models.

Edit the models.py file of the courses application and add the following field to the Course model:

students = models.ManyToManyField(User,
related_name='courses_joined',
blank=True)

From the shell, execute the following command to create a migration for this change:

python manage.py makemigrations

You will see an output similar to this:

Migrations for 'courses':
courses/migrations/0004_course_students.py
- Add field students to course

Then, execute the next command to apply pending migrations:

python manage.py migrate

You should see output that ends with the following line:

Applying courses.0004_course_students... OK

We can now associate students with the courses in which they are enrolled. Let's create the functionality for students to enroll in courses.

Create a new file inside the students application directory and name it forms.py. Add the following code to it:

from django import forms
from courses.models import Course

class CourseEnrollForm(forms.Form):
course = forms.ModelChoiceField(queryset=Course.objects.all(),
widget=forms.HiddenInput)

We are going to use this form for students to enroll in courses. The course field is for the course in which the user gets enrolled. Therefore, it's a ModelChoiceField. We use a HiddenInput widget because we are not going to show this field to the user. We are going to use this form in the CourseDetailView view to display a button to enroll.

Edit the views.py file of the students application and add the following code:

from django.views.generic.edit import FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from .forms import CourseEnrollForm

class StudentEnrollCourseView(LoginRequiredMixin, FormView):
course = None
form_class = CourseEnrollForm

def form_valid(self, form):
self.course = form.cleaned_data['course']
self.course.students.add(self.request.user)
return super(StudentEnrollCourseView,
self).form_valid(form)

def get_success_url(self):
return reverse_lazy('student_course_detail',
args=[self.course.id])

This is the StudentEnrollCourseView. view. It handles students enrolling in courses. The view inherits from the LoginRequiredMixin mixin so that only logged in users can access the view. It also inherits from Django's FormView view since we handle a form submission. We use the CourseEnrollForm form for the form_class attribute and also define a course attribute for storing the given Course object. When the form is valid, we add the current user to the students enrolled in the course.

The get_success_url() method returns the URL the user will be redirected to if the form was successfully submitted. This method is equivalent to the success_url attribute. We reverse the student_course_detail URL, which we will create in the next Accessing the course contents section in order to display the course contents.

Edit the urls.py file of the students application and add the following URL pattern to it:

path('enroll-course/',
views.StudentEnrollCourseView.as_view(),
name='student_enroll_course'),

Let's add the enroll button form to the course overview page. Edit the views.py file of the courses application and modify CourseDetailView to make it look as follows:

from students.forms import CourseEnrollForm

class CourseDetailView(DetailView):
model = Course
template_name = 'courses/course/detail.html'

def get_context_data(self, **kwargs):
context = super(CourseDetailView,
self).get_context_data(**kwargs)
context['enroll_form'] = CourseEnrollForm(
initial={'course':self.object})
return context

We use the get_context_data() method to include the enrollment form in the context for rendering the templates. We initialize the hidden course field of the form with the current Course object, so that it can be submitted directly.

Edit the courses/course/detail.html template and find the following line:

{{ object.overview|linebreaks }}

Replace it with the following code:

{{ object.overview|linebreaks }}
{% if request.user.is_authenticated %}
<form action="{% url "student_enroll_course" %}" method="post">
{{ enroll_form }}
{% csrf_token %}
<input type="submit" class="button" value="Enroll now">
</form>
{% else %}
<a href="{% url "student_registration" %}" class="button">
Register to enroll
</a>
{% endif %}

This is the button for enrolling in courses. If the user is authenticated, we display the enrollment button, including the hidden form that points to the student_enroll_course URL. If the user is not authenticated, we display a link to register in the platform.

Make sure the development server is running, open http://127.0.0.1:8000/ in your browser and click a course. If you are logged in, you should see an ENROLL NOW button placed below the course overview, as follows:

If you are not logged in, you will see a REGISTER TO ENROLL button instead.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.35.193