美文网首页零基础使用Django2.0.1打造在线教育网站
零基础使用Django2.0.1打造在线教育网站(十九):课程详

零基础使用Django2.0.1打造在线教育网站(十九):课程详

作者: 啃饼小白 | 来源:发表于2018-08-11 11:12 被阅读7次

    写在前面

    本篇笔记我们将介绍课程详情页面的配置,这个页面和我们之前配置的页面差别不是很大,可以借鉴前面的配置。

    本篇笔记对应于第十九篇代码,对应于github的位置是https://github.com/licheetools/eduline

    总结一下

    小伙伴们可能会问了,这篇笔记还没开始写怎么就开始总结了呢?是的,尽管没写但是我觉得非常有必要在这里总结一下,特别是对之前讲的信息的总结。后面随着开发进度的加快,一些东西我就不会详细介绍了,因为都是非常类似的操作。

    我们现在可以理解MTV的模式就应该是这样子的:新建数据库字段(models)-->配置访问路径(urls) -->新建视图函数(views) --> 页面信息动态加载(templates),所以后面的操作就是这个过程,大家在学习的时候对此要有一个清醒的认识。

    话不多说,我们正式进入今天的学习内容,走你。

    课程列表页配置

    老规矩,把前端资料里面的course-list.html页面拷贝到我们的templates文件夹里面,接着配置url,在eduline/urls.py文件新增如下代码:

    # 课程相关应用path配置
    path("course/", include('courses.urls', namespace="course")),
    

    然后打开courses应用,在里面新建urls.py文件并在里面新增如下代码:

    from django.urls import path, include, re_path
    from .views import CourseListView
    
    app_name = "courses"
    
    urlpatterns = [
        path('list/', CourseListView.as_view(), name='course_list'),
    
    ]
    

    现在打开courses/views.py文件,我们添加如下代码:

    from django.shortcuts import render
    from django.views.generic.base import View
    # Create your views here.
    
    
    class CourseListView(View):
        def get(self, request):
            return render(request, "course-list.html", {})
    

    运行一下我们的项目,在浏览器地址栏输入:http://127.0.0.1:8000/course/list/然后回车出现:

    可以发现访问没有问题,但是样式并没有加载出来。我们仔细观察course_list.html页面之后发现它和之前的org_list.html页面一样是具有共同的头部和尾部,因此我们可以继承base.html页面。

    在course_list.html里面删除所有代码,新增以下代码:

    {% extends 'base.html' %}
    {% load staticfiles %}
    {% block title %}公开课列表 - 慕海学习网{% endblock %}
    {% block custom_bread %}
    <section>
            <div class="wp">
                <ul  class="crumbs">
                    <li><a href="{% url 'index' %}">首页</a>></li>
                    <li>公开课</li>
                </ul>
            </div>
    </section>
    {% endblock %}
    
    {% block content %}
        <section>   <!--这里面的 <section> 就是课程信息,是通过观测来的-->
    {% endblock %}
    
    就是这个样子:

    然后是回到我们的courses/views.py文件,我们修改代码如下:

    from django.shortcuts import render
    from django.views.generic.base import View
    # Create your views here.
    from .models import Course
    
    
    class CourseListView(View):
        def get(self, request):
            all_courses = Course.objects.all()
            return render(request, "course-list.html", {
                "all_courses": all_courses,
            })
    
    回到course_list.html页面,修改代码为图示信息:

    分页功能配置

    直接仿照我们当时在org_list.html的配置,拷贝如下代码至courses/views.py文件里面:

    from pure_pagination import Paginator, EmptyPage, PageNotAnInteger
    
    # 对课程进行分页,尝试获取前端get请求传递过来的page参数
            # 如果是不合法的配置参数则默认返回第一页
            try:
                page = request.GET.get('page', 1)
            except PageNotAnInteger:
                page = 1
            # 这里指从all_courses中取出来,每页显示9个
            p = Paginator(all_courses, 9, request=request)
    
            courses = p.page(page)
            return render(request, "course-list.html", {
                "all_courses": courses,
            })
    
    接着打开course_list.html文件,修改代码为图示:

    在html中注意此刻不再是all_courses,前面说过此时的all_courses已经不是一个queryset对象,而是一个purepage对象,所以应该用all_courses.object_list。

    还有复制org_list的页面分页代码,并将all_orgs修改为all_courses,就是这段代码:

     <div class="pageturn">
                                <ul class="pagelist">
                                    {% if all_courses.has_previous %}
                                        <li class="long"><a href="?{{ all_courses.previous_page_number.querystring }}">上一页</a>
                                        </li>
                                    {% endif %}
                                    {% for page in all_courses.pages %}
                                        {% if page %}
                                            {% ifequal page all_courses.number %}
                                                <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li>
                                            {% else %}
                                                <li><a href="?{{ page.querystring }}">{{ page }}</a></li>
                                            {% endifequal %}
                                        {% else %}
                                            <li class="none"><a href="">...</a></li>
                                        {% endif %}
                                    {% endfor %}
                                    {% if all_courses.has_next %}
                                        <li class="long"><a href="?{{ all_courses.next_page_number.querystring }}">下一页</a></li>
                                    {% endif %}
                                </ul>
                            </div>
    

    排序功能的配置


    和前面在org_list页面的配置一模一样,我们复制粘贴并修改一下那些代码,放到courses/views.py文件里面:

    all_courses = Course.objects.all().order_by("-add_time") # 默认是按添加顺序反着排序
    # 最热门和参与人数排名
            # 最热门hot根据点击数来判断
            # 参与人数是根据学习人数来判断
            sort = request.GET.get('sort', '')
            if sort:
                if sort == "students":
                    all_courses = all_courses.order_by("-students")
                elif sort == "hot":
                    all_courses = all_courses.order_by("-click_nums")
    
    return render(request, "course-list.html", {
                "sort": sort,
            })
    
    

    现在打开course_list.html文件,我们将上述功能和选中状态进行配置:

    <ul class="tab_header">
                            <li class="{% ifequal sort '' %}active{% endifequal %}"><a href="?sort=">最新 </a></li>
                            <li class="{% ifequal sort 'hot' %}active{% endifequal %}"><a href="?sort=hot">最热门</a></li>
                            <li class="{% ifequal sort 'students' %}active{% endifequal %}"><a href="?sort=students">参与人数</a></li>
                        </ul>
    
    就是这个样子:

    热门课程推荐

    打开courses/views.py文件,新增以下代码:

      # 热门课程推荐
            hot_courses = Course.objects.all().order_by("-students")[:3]
           return render(request, "course-list.html", {
                "hot_courses": hot_courses,
            })
    

    然后打开course_list.html文件,将热门课程推荐进行动态加载:


    运行一下我们的项目,在浏览器地址栏输入http://127.0.0.1:8000/course/list/回车,发现课程难度显示有问题:

    我们需要修改{ hot_course.degree }}{ hot_course.get_degree_display }},这个字段的意思是说得到degree的字段显示,并不是得到它本身,事实上它本身为英文。(专门针对choices的显示)

    现在刷新一下我们的页面,难度等级正常显示了,没有问题:

    至此课程列表页的介绍到此结束,下面我们介绍课程详情页面。

    课程详情页配置

    老规矩,把前端资料里面的course-detail.html页面拷贝到我们的templates文件夹里面,正常情况下我们应该配置url,但是鉴于此处的course-detail.html页面会继承我们之前的course-list.html页面,所以我们就先把course-detail.html页面给配置完,然后才开始url的配置。

    打开course-detail.html页面,删除所有代码,新增以下代码:

    {% extends 'base.html' %}
    {% load staticfiles %}
    {% block title %}课程详情页 - 慕海学习网{% endblock %}
    {% block custom_bread %}
    <section>
            <div class="wp">
                <ul  class="crumbs">
                    <li><a href="{% url 'index' %}">首页</a>></li>
                    <li><a href="{% url 'course:course_list' %}">公开课程</a>></li>
                    <li>{{ course.name }}</li>
                </ul>
            </div>
    </section>
    {% endblock %}
    
    {% block content %}
        <section>
        <section>   <!--这里面的 <section> 就是课程信息,是通过观测来的-->
    {% endblock %}
    
    

    接着配置url,打开courses/urls.py文件并在里面新增如下代码:

    from .views import CourseDetailView
    
     # 课程机构首页url
        re_path('detail/(?P<course_id>.*)/', CourseDetailView.as_view(), name="course_detail"),
    

    现在书写我们的视图函数,打开courses/views.py文件,在里面添加如下代码:

    # 课程详情页
    class CourseDetailView(View):
        def get(self, request,course_id):  # 所有re_path在请求参数的时候必须带上id
            return render(request, "course-detail.html", {})
    
    然后配置页面的跳转链接,我们希望可以从课程列表页面跳转进来,所以打开course_list.html页面,将图中信息修改为所示信息:

    接下来修改我们的view(courses/views.py文件),准备页面信息的动态加载:

    # 课程详情页
    class CourseDetailView(View):
        def get(self, request, course_id):
    #注意一下此处的id是数据库表默认为我们添加的
            course = Course.objects.get(id=int(course_id))
            return render(request, "course-detail.html", {
                "course": course,
            })
    

    然后打开course_detail.html页面,使我们的数据得到动态加载并显示出来。

    注意章节数和学习用户的获取方式:在courses/modles.py文件里面的Course类里面定义一个get-zj-nums方法:

        def get_zj_nums(self):
            # 获取课程章节数
            return self.lesson_set.all().count()
    

    还有学习用户的获取方式:我们之前在operation中专门定义了一个类UserCourse用于对用户学习作记录的。既然存在了这个类(数据库生成和迁移操作之后是一张表),那我们就可以采用获取学习章节数的方式来获取它。

    同样在courses/modles.py文件里面的Course类里面定义一个get-learn-users方法:

         def get_learn_users(self):
            # 获取学习用户数,此处不用统计,我们只取出5个即可
            return self.usercourse_set.all()[:5] 
    
    就是这个样子:
    现在打开course_detail.html页面,将信息修改为图示那样:
    然后去xadmin后台新增用户课程,记得把刚才展示的课程加里面去,便于我们观察是否成功显示:
    还有一个问题,就是你现在点进这个页面,那么相应课程的点击数应该加1,所以在我们的view(courses/views.py文件),新增以下代码:
    # 课程点击数增加
            course.click_nums += 1
            course.save()
    
    
    就是这个样子:

    授课机构的配置


    注意教师数的获取方式:
    注意章节数和学习用户的获取方式:在organization/modles.py文件里面的CourseOrg类里面定义一个get_teacher_nums方法:

            def get_teacher_nums(self):
            # 获取教师数
            return self.teacher_set.all().count()
    

    然后html页面调用,采用如下代码:

    {{ course.course_org.get_teacher_nums }}
    
    

    当然如果你不想自定义函数,那也是可以的,你仅仅只需要在前端页面采用如下代码即可,是不是更简单:

    {{ course.course_org.teacher_set.count }}
    

    接下来我们完成右侧下面的相关课程推荐模块。

    相关课程推荐

    这个就是相关课程推荐的页面,我们接下来就是完成这个功能:

    打开courses/views.py文件,在CourseDetailView函数里面新增用于实现相关课程推荐功能的代码:

    # 相关课程推荐
            # 此处为course而不是Course,我们是用前面取出的课程
            tag = course.tag
            if tag:
    #  这里必须从1开始不然会推荐自己,也就是索引0
                relate_courses = Course.objects.filter(tag=tag)[1:2]
            else:
                relate_courses = []
     return render(request, "course-detail.html", {
                "relate_courses": relate_courses,
            })
    

    就是这个样子:


    接着在course-detail.html页面修改页面展示信息:
    {% for relate_course in relate_courses %}
                            <dl>
                                <dt>
                                    <a target="_blank" href="{% url 'course:course_detail' relate_course.id %}">
                                        <img width="240" height="220" class="scrollLoading"
                                             src="{{ MEDIA_URL }}{{ relate_course.image }}"/>
                                    </a>
                                </dt>
                                <dd>
                                    <a target="_blank" href="{% url 'course:course_detail' relate_course.id %}">
                                        <h2>{{ relate_course.name }}</h2></a>
                                    <span class="fl">学习时长:<i class="key">{{ relate_course.learn_times }}</i></span>
                                </dd>
                            </dl>
                        {% endfor %}
    
    就是这个样子: 然后去xadmin后台或者数据库中将几个课程的tag修改为同一个,然后再运行一下我们的项目,就出现:

    现在还差页面中的收藏和开始学习这两个功能的配置了,开始学习我们在下一篇介绍。

    实现收藏功能

    我们之前在课程机构里面配置过收藏的功能,如果不熟悉的小伙伴们可以回顾一下第十八篇:
    零基础使用Django2.0.1打造在线教育网站(十八):机构详情页配置,这里我就快速介绍一下:
    首先在course-detail.html页面底部添加如下代码:

    {% block custom_js %}
        <script type="text/javascript">
            //收藏分享
            function add_fav(current_elem, fav_id, fav_type) {
                $.ajax({
                    cache: false,
                    type: "POST",
                    url: "{% url "org:add_fav" %}",
                    data: {'fav_id': fav_id, 'fav_type': fav_type},
                    async: true,
                    beforeSend: function (xhr, settings) {
                        xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
                    },
                    success: function (data) {
                        if (data.status == 'fail') {
                            if (data.msg == '用户未登录') {
                                window.location.href = "{% url 'login' %}?next={{ request.path }}";
                            } else {
                                alert(data.msg)
                            }
    
                        } else if (data.status == 'success') {
                            current_elem.text(data.msg)
                        }
                    },
                });
            }
    
            $('#jsLeftBtn').on('click', function () {
                add_fav($(this), {{ course.id }}, 1);
            });
    
            $('#jsRightBtn').on('click', function () {
                add_fav($(this), {{ course.course_org.id }}, 2);
            });
    
        </script>
    {% endblock %}
    

    然后再打开course/views.py文件,补充 CourseDetailView函数:

    from operation.models import UserFavorite
    
    
    # 是否收藏课程,默认为否
            has_fav_course = False
            has_fav_org = False
    
            # 用户必须已登录我们才判断,否则不需要
            if request.user.is_authenticated:
                if UserFavorite.objects.filter(user=request.user, fav_id=course.id, fav_type=1):
                    has_fav_course = True
                if UserFavorite.objects.filter(user=request.user, fav_id=course.course_org.id, fav_type=2):
                    has_fav_org = True
    
    return render(request, "course-detail.html", {
                "has_fav_course": has_fav_course,
                "has_fav_org": has_fav_org,
            })
    
    

    就是这个样子:


    接着打开course-detail.html页面,修改收藏的显示:
    <div class="btn colectgroupbtn"  id="jsLeftBtn">
                                      {% if has_fav_course %}已收藏{% else %}收藏{% endif %}
                                </div>
    
    
    <div class="btn  notlogin
                             "data-favid="14" id="jsRightBtn">
                             {% if has_fav_org %}已收藏{% else %}收藏{% endif %}
                        </div>
    
    运行一下项目,两个都点击试试:

    数据库已经有了,点击就没有了。

    备注

    • 如果出现上面两个收藏按钮点击没反应的情况,大家可以先尝试用浏览器f12(博主用的是chrome浏览器)看一下浏览器有没有post请求发出去以及参数和url的配置是否出错。如果还是有问题,那么回到base.html页面,将{% block custom_js %}{% endblock %}的位置由开头放置到底部:
      原来:
      现在:

    知道为什么会出现这种情况么?那是因为jQuery 入口函数与 JavaScript 入口函数是有区别的:jQuery 的入口函数是在 html 所有标签(DOM)都加载之后,就会去执行。而JavaScript 的 window.onload 事件是等到所有内容,包括外部图片之类的文件加载完后,才会执行的。这里是js还未加载完就去执行,所以才出现的问题,放在底部就没问题了。

    至此本篇关于课程详情页面的配置介绍就到此结束了,感谢你的赏阅。

    本篇笔记对应于第十九篇代码,对应于github的位置是https://github.com/licheetools/eduline

    相关文章

      网友评论

        本文标题:零基础使用Django2.0.1打造在线教育网站(十九):课程详

        本文链接:https://www.haomeiwen.com/subject/pgbgvftx.html