写在前面
本篇笔记我们将介绍机构详情页面的配置,主要包括四个部分:机构首页、机构课程、机构介绍和机构讲师,以及用户收藏的介绍下面我将逐一介绍说明。
本篇笔记对应于第十八篇代码,对应于github的位置是https://github.com/licheetools/eduline。
机构首页
打开浏览器,在地址栏输入:http://127.0.0.1:8000/xadmin,往里面新增10门课程和10位讲师信息:
新增课程信息的时候发现课程没有所属课程机构,这是不行的,因为我们后面还有机构课程这个模块,如果课程与课程机构之间没有外键来链接的话就无法实现相应的功能。
所以我们需要在courses/models.py文件中,新增外键连接:
from organization.models import CourseOrg
course_org = models.ForeignKey(CourseOrg, on_delete=models.CASCADE, verbose_name="课程机构", null=True, blank=True)
就是这个样子:
记住我们需要在外键里面增加要求
null=True, blank=True
,你可能会问,为什么之前的外键不用呢?那是因为之前没有课程数据,可是现在里面已经有了一门课程(之前添加的),如果不加这个要求,系统会提示之前的那门课的外键怎么办。所以为了避免这个问题,我们就加上这个要求。
接下来进行数据库的生成和迁移操作:
makemigration courses
migrate courses
就是这个样子:
然后继续在xadmin后台新增课程信息: 完成以后,现在将前端资料里面与org相关的四个页面拷贝到我们的templates文件夹里面:接下来,通过观察新建org_base.html页面,将org_homepage页面全部复制过去,然后修改block:
接下来就是三部曲了:
1、页面第三行加上{% load staticfiles %}
2、修改全部类型文件的static相对路径
3、修改其中已经设置好的url,配置跳转链接
现在仿照之前的Base继承,清空org_homepage页面,往里面新增图示代码:
然后删除org_base.html页面中的
{% block right_form %}
和{% endblock %}
之间的代码,就是这个样子:
接下来打开我们的organization/views.py文件,在底部新增如下代码:
# 机构首页
class OrgHomeView(View):
def get(self, request, org_id):
# 根据id来获取课程机构
course_org = CourseOrg.objects.get(id=int(org_id))
# 根据取到的课程机构直接获取它的所有课程,我们取3个
all_courses = course_org.course_set.all()[:3]
# 根据取到的课程机构直接获取它的所有讲师,我们取1个
all_teachers = course_org.teacher_set.all()[:1]
render(request, "org-detail-homepage.html", {
"all_courses": all_courses,
"all_teachers": all_teachers,
})
然后配置我们的path,打开organization/urls.py文件,在底部新增如下代码:
from .views import OrgHomeView
# 课程机构首页url,此处不是普通的url是因为我们必须知道是哪个机构的首页
re_path('home/(?P<org_id>.*)/', OrgHomeView.as_view(), name="org_home"),
接着打开org_homepage页面,删除多余的课程,采用for循环来遍历数据库中的课程信息:
顺便修改其中的课程信息:
{% for course in all_courses %}
<div class="module1_5 box">
<a href="course-detail.html"><img width="214" src="{{ MEDIA_URL }}{{ course.image }}"/></a>
<div class="des">
<a href="course-detail.html"><h2>{{ course.name }}</h2></a>
<span class="fl">课时:<i class="key">{{ course.learn_times }}</i></span>
<span class="fr">参加人数:{{ course.students }}</span>
</div>
<div class="bottom">
<span class="fl">{{ course.course_org.name }}</span>
<span class="star fr notlogin
" data-favid="13" data-fav-type="4">
{{ course.fav_nums }}
</span>
</div>
</div>
{% endfor %}
然后三部曲走一下,这里就不详细说明了。
接着打开org_list页面,配置跳转链接:
修改如下:
<a href="{% url 'org:org_home' course_org.id %}">
记住因为之前我们的org_home配置的不是普通的path,所以你如果写成普通的:
<a href="{% url 'org:org_home' %}">
那是会报错的,我们需要在此后空一格,然后带上我们在path中定义的id,因为是跳转到课程机构首页,所以写上它的id。
然后运行一下我们的项目:发现课程机构显示不同步,那我们把刚才获取到的数据返回到页面显示一下:那我们就打开我们的organization/views.py文件,在底部修改为如下代码:
# 机构首页
class OrgHomeView(View):
def get(self, request, org_id):
# 根据id来获取课程机构
course_org = CourseOrg.objects.get(id=int(org_id))
# 根据取到的课程机构直接获取它的所有课程,我们取3个
all_courses = course_org.course_set.all()[:3]
# 根据取到的课程机构直接获取它的所有讲师,我们取1个
all_teachers = course_org.teacher_set.all()[:1]
render(request, "org-detail-homepage.html", {
"all_courses": all_courses,
"all_teachers": all_teachers,
"course_org": course_org,
})
接着返回org_base页面,我们修改如下代码:
这里的数据会向上传递,所以后面的那些org页面都是可以用到的。完成以后就是这个样子:
接着运行一下我们的项目,发现显示没有问题:
下面继续完成它的其余两个:机构教师和机构介绍。
机构介绍:还是在org_homepage页面,将信息修改成图示:
接着运行一下我们的项目,发现显示没有问题。
至此,第一个机构首页的信息就全部配置完全了,其余几个很类似,所以介绍的就比较快了,当做复习一下。
机构课程
打开org-detail_course.html页面,将org_home页面代码全部复制进去(放在上面,最好和现有代码有一个清楚的界限),再将图中所指的复制进入org-detail_course页面的{% block right_form %}
和{% endblock %}之间
:
然后将其余代码删除,顺便修改标题的内容,就是这个样子:
接下来打开我们的organization/views.py文件,在底部新增如下代码:
# 机构课程列表页
class OrgCourseView(View):
def get(self, request, org_id):
# 根据id来获取课程机构
course_org = CourseOrg.objects.get(id=int(org_id))
# 根据取到的课程机构直接获取它的所有课程
all_courses = course_org.course_set.all()
return render(request, "org-detail-course.html", {
"all_courses": all_courses,
"course_org": course_org,
})
然后配置我们的path,打开organization/urls.py文件,在底部新增如下代码:
from .views import OrgCourseView
# 机构课程列表页url,此处不是普通的url是因为我们必须知道是哪个机构的课程列表页
re_path('course/(?P<org_id>.*)/', OrgCourseView.as_view(), name="org_course"),
现在打开org_base.html页面,设置页面跳转:
接下来就是展示数据库的信息了,打开org-detail_course.html页面,将图中信息修改为图中所示:
刷新一下我们的页面:
我们发现我们的机构课程明明选中了,可是还是灰色,所以我们需要配置选中状态:
我们打开organization/views.py文件,在图示位置(OrgHomeView函数里面)加上图示信息:
current_page = "home"
return render(request, "org-detail-homepage.html", {
"current_page": current_page,
})
这是为了让前端页面知道什么情况下等于什么,就处于何种选中状态。
接着打开base.html页面,修改图示代码为图中所示,下面2个你照敲就可以:刷新一下我们的页面,没有问题:
但是我们发现面包屑的提示还是没有发生变化,所以我们需要设置一下:
将org-detail_course.html页面开头代码修改如下:
{% block page_path %}机构课程{% endblock %}
{% block title %}机构课程详情页 | 慕海学习网{% endblock %}
就是这个样子:
现在我们再来刷新一下我们的页面,没有问题:
机构介绍
在前端资料里面,机构介绍是org_detail_desc.html页面,我们在此之前已经发现有关课程机构的页面其实都是类似的,只不过右边栏不同,左边除了路径其余是一模一样,所以我们可以在已完成的org-detail_course.html页面把右边的东西用org_detail_desc.html的页面来替换掉,其余的就都可以删除了。
首先,复制org-detail_course.html页面的全部代码,放到org_detail_desc.html页面的前部,找到org_detail_desc.html页面的<div class="right companycenter layout" >
,复制它并将之前从org_detail_desc.html页面复制的同名<div class="right companycenter layout" >
替换掉,并删除多余代码,之后org_detail_desc.html页面就成了这个样子:
接下来打开我们的organization/views.py文件,在底部新增如下代码:
# 机构课程详情页
class OrgDescView(View):
def get(self, request, org_id):
current_page = "desc"
# 根据id来获取课程机构
course_org = CourseOrg.objects.get(id=int(org_id))
return render(request, "org-detail-desc.html", {
"course_org": course_org,
"current_page": current_page,
})
然后配置我们的path,打开organization/urls.py文件,在底部新增如下代码:
from .views import OrgDescView
# 机构课程详情页url
re_path('desc/(?P<org_id>.*)/', OrgDescView.as_view(), name="org_desc"),
现在打开org_base.html页面,设置页面跳转:
然后打开org_detail_desc.html页面,配置数据的动态加载:
运行一下我们的项目,在浏览器地址栏输入:http://127.0.0.1:8000/org/desc回车,发现页面没有问题:
机构讲师
首先,复制org-detail_desc.html页面的全部代码,放到org_detail_teachers.html页面的前部,找到org_detail_teachers.html页面的<div class="right companycenter layout" >
,复制它并将之前从org_detail_desc.html页面复制的同名<div class="right companycenter layout" >
替换掉,并删除多余代码,之后org_detail_teachers.html页面就成了这个样子:
接下来打开我们的organization/views.py文件,在底部新增如下代码:
# 机构讲师列表页
class OrgTeacherView(View):
def get(self, request, org_id):
current_page = "teachers"
# 根据id来获取课程机构
course_org = CourseOrg.objects.get(id=int(org_id))
# 根据取到的课程机构直接获取它的所有讲师
all_teachers = course_org.teacher_set.all()
return render(request, "org-detail-teachers.html", {
"course_org": course_org,
"current_page": current_page,
"all_teachers": all_teachers,
})
然后配置我们的path,打开organization/urls.py文件,在底部新增如下代码:
from .views import OrgTeacherView
# 机构讲师详情页url
re_path('teacher/(?P<org_id>.*)/', OrgTeacherView.as_view(), name="org_teacher"),
现在打开org_base.html页面,设置页面跳转:
运行一下我们的项目,在浏览器地址栏输入:http://127.0.0.1:8000/org/teacher回车,发现页面没有问题,不过讲师头像信息还没加载出来,我们去html动态加载一下:
最后是这个样子:
课程数我们目前先不替换它,后面会换掉! 接着我们刷新一下我们的页面,没有问题: 最后在org_base.html页面配置跳转链接:
用户收藏
接下来我们完成右侧的用户收藏,它和之前的我要学习页面一样是通过Ajax来加载的。
首先打开我们的organization/views.py文件,在底部新增如下代码:
from operation.models import UserFavorite
# 用户收藏与取消收藏功能
class AddFavView(View):
def post(self, request):
fav_id = request.POST.get('fav_id', 0) # 尽管我们取出的是字符串,但是后面会进行整型转换,空字符串转换会出错
fav_type = request.POST.get('fav_type', 0)
# 收藏和已收藏取消收藏
# 判断用户是否登录,即使没登录也会有一个匿名的user
if not request.user.is_authenticated:
return HttpResponse('{"status":"fail", "msg":"用户未登录"}', content_type='application/json')
exist_records = UserFavorite.objects.filter(user=request.user, fav_id=int(fav_id), fav_type=int(fav_type))
if exist_records:
# 如果记录已经存在,那我们删除它就表示用户取消收藏
exist_records.delete()
# 删除完,页面显示收藏
return HttpResponse('{"status":"success", "msg":"收藏"}', content_type='application/json')
else:
# 记录不存在,那我们就添加一条数据进入数据库里面
user_fav = UserFavorite() # 实例化一个对象
if int(fav_id)>0 and int(fav_type)>0:
user_fav.id = int(fav_id)
user_fav.fav_type = int(fav_type)
user_fav.user = request.user
user_fav.save()
# 收藏成功
return HttpResponse('{"status":"success", "msg":"已收藏"}', content_type='application/json')
else:
# 收藏出错
return HttpResponse('{"status":"fail", "msg":"收藏出错"}', content_type='application/json')
然后配置我们的path,打开organization/urls.py文件,在底部新增如下代码:
from .views import AddFavView
# 用户收藏与取消收藏url,注意这是普通的url
path("add_fav/", AddFavView.as_view(), name="add_fav"),
接下来打开我们的org_base.html页面,修改其中的代码为图示:
然后打开我们的organization/views.py文件,修改我们的OrgHomeView,新增以下代码:
has_fav = False
if request.user.is_authenticated:
if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2):
has_fav = True
return render(request, "org-detail-homepage.html", {
"has_fav": has_fav,
})
就是这个样子:
接着打开我们的org_base.html页面,ctrl+f 搜索收藏,配置页面显示:
{% if has_fav %}
已收藏
{% else %}
收藏
{% endif %}
就是这个样子:
然后刷新页面,没有问题。
接下来我们对其余3个view都添加以下代码:
has_fav = False
if request.user.is_authenticated:
if UserFavorite.objects.filter(user=request.user, fav_id=course_org.id, fav_type=2):
has_fav = True
return render(request, "org-detail-homepage.html", {
"has_fav": has_fav,
})
最后将注册登录状态放置到页面里面去,具体操作是;打开index.html页面,将{% if request.user.is_authenticated %}
和{% endif %}
里面的代码复制到org_base.html页面,具体放置位置如图:
现在刷新一下我们的页面,没有问题:
项目做完以后,我想到了一个问题:你机构类型的增加和减少势必会影响到该类型喜欢人数的增减,所以我们必须对之前的AddFavView函数进行修改,这里我附上修改后的代码(把AddFavView函数内容删除):
from organization.models import Teacher
# 用户收藏与取消收藏功能
class AddFavView(View):
def post(self, request):
# 取出fav_id,尽管是字符串类型,但是我们后面会进行整型转换,所以默认为0
fav_id = request.POST.get('fav_id', 0)
# 取到fav_type,尽管是字符串类型,但是我们后面会进行整型转换,所以默认为0
fav_type = request.POST.get('fav_type', 0)
# 未收藏时收藏和已收藏时取消收藏
# 判断用户是否登录,即使用户没有登录会有一个匿名的user
if not request.user.is_authenticated:
# 未登录时页面提示未登录,并跳转到登录页面
return HttpResponse('{"status":"fail", "msg":"用户未登录"}', content_type='application/json')
exist_records = UserFavorite.objects.filter(user=request.user, fav_id=int(fav_id), fav_type=int(fav_type))
if exist_records:
# 如果记录已经存在, 那么用户就可以取消收藏
exist_records.delete()
# 下面是根据收藏类型来进行删除,同时删除后机构类型对应的喜欢人数也会减一
if int(fav_type) == 1:
course = Course.objects.get(id=int(fav_id))
course.fav_nums -= 1
course.save()
if course.fav_nums <= 0:
course.fav_nums = 0
elif int(fav_type) == 2:
course_org = CourseOrg.objects.get(id=int(fav_id))
course_org.fav_nums -= 1
course_org.save()
if course_org.fav_nums <= 0:
course_org.fav_nums = 0
elif int(fav_type) == 3:
teacher = Teacher.objects.get(id=int(fav_id))
teacher.fav_nums -= 1
teacher.save()
if teacher.fav_nums <= 0:
teacher.fav_nums = 0
return HttpResponse('{"status":"success", "msg":"收藏"}', content_type='application/json')
else:
user_fav = UserFavorite()
# 过滤掉未取到fav_id type的默认情况
if int(fav_type) > 0 and int(fav_id) > 0:
user_fav.user = request.user
user_fav.fav_id = int(fav_id)
user_fav.fav_type = int(fav_type)
user_fav.save()
# 下面是根据收藏类型来进行增加,同时增加记录后机构类型对应的喜欢人数也会加一
if int(fav_type) == 1:
course = Course.objects.get(id=int(fav_id))
course.fav_nums += 1
course.save()
elif int(fav_type) == 2:
course_org = CourseOrg.objects.get(id=int(fav_id))
course_org.fav_nums += 1
course_org.save()
elif int(fav_type) == 3:
teacher = Teacher.objects.get(id=int(fav_id))
teacher.fav_nums += 1
teacher.save()
return HttpResponse('{"status":"success", "msg":"已收藏"}', content_type='application/json')
else:
return HttpResponse('{"status":"fail", "msg":"收藏出错"}', content_type='application/json')
注意:+=,-=表示将前者与后者之和(差)的结果重新赋值给前者,例如a+=b表示 a=a+b,c-=d表示 c =c -d。注意一下,在Python里面是没有++,--的,在java里面是有的,表示自加(减)1
至此,本篇关于机构详情页面的配置以及用户收藏的介绍就到此为止了,感谢你的赏阅。
本篇笔记对应于第十八篇代码,对应于github的位置是https://github.com/licheetools/eduline。
网友评论