Django+Xadmin打造在线教育系统(七)

全局导航&个人中心&全局搜索

配置全局导航

让index页面也继承base页面,注意首页有个单独的__index.js__ base页面的导航栏也进行配置

<!--more-->
1 <nav> 2 <div class="nav"> 3 <div class="wp"> 4 <ul> 5 <li ><a href="{% url 'index' %}">首页</a></li> 6 <li > 7 <a href="{% url 'course:list' %}"> 8 公开课<img class="hot" src="{% static "images/nav_hot.png" %}"> 9 </a> 10 </li> 11 <li > 12 <a href="{% url 'org:teacher_list' %}">授课教师</a> 13 </li> 14 <li class="active" ><a href="{% url 'org:org_list' %}">授课机构</a></li> 15 </ul> 16 </div> 17 </div> 18 </nav>

但是现在我们不知道当前是哪一个页面,因为后端没有传值过来 这里可以使用request.path进行判断 比如http://127.0.0.1:8000/org/teacher_list/,则request.path 就是`/org/teacher_list/`` slice:12 是过滤器,取前12位数 利用这种方法可以达到全局的“active”效果,而不用每个子页面都要去设置“active”了

1 <ul> 2 <li {% if request.path == '/' %}class="active"{% endif %}><a href="{% url 'index' %}">首页</a></li> 3 <li {% if request.path|slice:'7' == '/course' %}class="active"{% endif %}> 4 <a href="{% url 'course:list' %}"> 5 公开课<img class="hot" src="{% static 'images/nav_hot.png' %}"> 6 </a> 7 </li> 8 <li {% if request.path|slice:'12' == '/org/teacher' %}class="active"{% endif %}> 9 <a href="{% url 'org:teacher_list' %}">授课教师</a> 10 </li > 11 <li {% if request.path|slice:'9' == '/org/list' %}class="active"{% endif %}> 12 <a href="{% url 'org:org_list' %}">授课机构</a></li> 13 </ul>

全局搜索功能

通过url中加参数keywords来达到全局搜索的功能

以Course搜索为例:

1 # 搜索功能 2 search_keywords = request.GET.get('keywords', '') 3 if search_keywords: 4 # icontains是包含的意思(不区分大小写) 5 # Q可以实现多个字段,之间是or的关系 6 all_course = all_course.filter( 7 Q(name__icontains=search_keywords) | Q(desc__icontains=search_keywords) | Q( 8 detail__icontains=search_keywords))

搜索的代码放在deco-common.js中 如果自己写的url和js文件中的不同,可自行修改

1//顶部搜索栏搜索方法 2function search_click(){ 3 var type = $('#jsSelectOption').attr('data-value'), 4 keywords = $('#search_keywords').val(), 5 request_url = ''; 6 if(keywords == ""){ 7 return 8 } 9 if(type == "course"){ 10 request_url = "/course/list?keywords="+keywords 11 }else if(type == "teacher"){ 12 request_url = "/org/teacher/list?keywords="+keywords 13 }else if(type == "org"){ 14 request_url = "/org/list?keywords="+keywords 15 } 16 window.location.href = request_url 17}

课程机构搜索功能

1 # 机构搜索功能 2 search_keywords = request.GET.get('keywords', '') 3 if search_keywords: 4 # 在name字段进行操作,做like语句的操作。i代表不区分大小写 5 # or操作使用Q 6 all_orgs = all_orgs.filter(Q(name__icontains=search_keywords) | Q(desc__icontains=search_keywords))

授课老师搜索功能

1 # 搜索功能 2 search_keywords = request.GET.get('keywords', '') 3 if search_keywords: 4 # 在name字段进行操作,做like语句的操作。i代表不区分大小写 5 # or操作使用Q 6 all_teachers = all_teacher.filter(name__icontains=search_keywords)

个人中心信息展示

新建usercenter-bae.html当模板 进行配置

1 path("users/", include('users.urls', namespace="users")), 2 3 4from django.urls import path 5 6from users.views import UserinfoView 7 8app_name = 'users' 9 10urlpatterns = [ 11 #用户信息 12 path("info/", UserinfoView.as_view(),name='user_info'), 13] 14 15 16class UserinfoView(LoginRequiredMixin,View): 17 '''用户个人信息''' 18 def get(self,request): 19 return render(request,'usercenter-info.html',{})

前端显示个人信息

1 <div class="right"> 2 <div class="personal_des "> 3 <div class="head" style="border:1px solid #eaeaea;"> 4 <h1>个人信息</h1> 5 </div> 6 <div class="inforcon"> 7 <div class="left" style="width:242px;"> 8 <iframe id='frameFile' name='frameFile' style='display: none;'></iframe> 9 <form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="/users/image/upload/" target='frameFile'> 10 <label class="changearea" for="avatarUp"> 11 <span id="avatardiv" class="pic"> 12 <img width="100" height="100" class="js-img-show" id="avatarShow" src="{{ MEDIA_URL }}{{ request.user.image }}"/> 13 </span> 14 <span class="fl upload-inp-box" style="margin-left:70px;"> 15 <span class="button btn-green btn-w100" id="jsAvatarBtn">修改头像</span> 16 <input type="file" name="image" id="avatarUp" class="js-img-up"/> 17 </span> 18 </label> 19 {% csrf_token %} 20 </form> 21 <div style="border-top:1px solid #eaeaea;margin-top:30px;"> 22 <a class="button btn-green btn-w100" id="jsUserResetPwd" style="margin:80px auto;width:100px;">修改密码</a> 23 </div> 24 </div> 25 <form class="perinform" id="jsEditUserForm" autocomplete="off"> 26 <ul class="right"> 27 <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;称: 28 <input type="text" name="nick_name" id="nick_name" value="{{ request.user.name }}" maxlength="10"> 29 <i class="error-tips"></i> 30 </li> 31 <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;日: 32 <input type="text" id="birth_day" name="birday" value="{{ request.user.birthday }}" readonly="readonly"/> 33 <i class="error-tips"></i> 34 </li> 35 <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;别: 36 <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" name="gender" value="male" 37 {% ifequal request.user.gender "male" %} 38 checked="checked" 39 {% endifequal %} 40 ></label> 41 <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" name="gender" value="female" 42 {% ifequal request.user.gender "female" %} 43 checked="checked" 44 {% endifequal %} 45 ></label> 46 </li> 47 <li class="p_infor_city">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;址: 48 <input type="text" name="address" id="address" placeholder="请输入你的地址" value="{{ request.user.address }}" maxlength="10"> 49 <i class="error-tips"></i> 50 </li> 51 <li>&nbsp;&nbsp;&nbsp;&nbsp;号: 52 <input type="text" name="mobile" id="mobile" placeholder="请输入你的手机号码" value="{{ request.user.mobile|default_if_none:'' }}" maxlength="11"> 53 </li> 54 <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱: 55 <input class="borderno" type="text" name="email" readonly="readonly" value="{{ request.user.email }}"/> 56 <span class="green changeemai_btn">[修改]</span> 57 </li> 58 <li class="button heibtn"> 59 <input type="button" id="jsEditUserBtn" value="保存"> 60 </li> 61 </ul> 62 {% csrf_token %} 63 </form> 64 </div> 65 </div> 66 </div>

修改密码和修改头像

1 #用户图像上传 2 path("image/upload/", UploadImageView.as_view(),name='image_upload'),

新建一个用于保存图片的form 这里继承的是ModelForm,该类具有save功能

1# 用于文件上传,修改头像 2class UploadImageForm(forms.ModelForm): 3 4 class Meta: 5 model = UserProfile 6 fields = ['image'] 7 8 9class UploadImageView(LoginRequiredMixin,View): 10 '''用户图像修改''' 11 def post(self,request): 12 # 这时候用户上传的文件就已经被保存到image_form了 ,为modelform添加instance值直接保存 13 image_form = UploadImageForm(request.POST, request.FILES, instance=request.user) 14 if image_form.is_valid(): 15 image_form.save() 16 # 所有验证通过的字段放在cleaned data 17 # # 取出cleaned data中的值,一个dict 18 # image = image_form.cleaned_data['image'] 19 # request.user.image = image 20 # request.user.save() 21 return HttpResponse('{"status":"success"}', content_type='application/json') 22 else: 23 return HttpResponse('{"status":"fail"}', content_type='application/json') 24 25 26#用户个人中心修改密码 27 path("update/pwd/", UpdatePwdView.as_view(),name='update_pwd'), 28 29 30# 在个人中心修改用户密码 31class UpdatePwdView(View): 32 def post(self, request): 33 modiypwd_form = ModifyPwdForm(request.POST) 34 if modiypwd_form.is_valid(): 35 pwd1 = request.POST.get("password1", "") 36 pwd2 = request.POST.get("password2", "") 37 # 如果两次密码不相等,返回错误信息 38 if pwd1 != pwd2: 39 return HttpResponse('{"status":"fail", "msg":"密码不一致"}', content_type='application/json') 40 # 如果密码一致 41 user =request.user 42 # 加密成密文 43 user.password = make_password(pwd2) 44 # save保存到数据库 45 user.save() 46 return HttpResponse('{"status":"success"}', content_type='application/json') 47 # 验证失败说明密码位数不够。 48 else: 49 return HttpResponse('{"status":"fail", "msg":"填写错误请检查"}', content_type='application/json')

Ajxa代码放在deco-user.js里面 如果url不正确可自行配置' 如果遇到403,检查base中的csrf_token是否填写

发送修改邮箱验证码

有两个接口需要完成。点击获取验证码时,后台需要向用户新邮箱发送验证码。 邮箱如果出错,会返回错误信息。 输入了邮箱和验证码,验证是否匹配。 给EmailVerifyRecord再添加一个选择类型

1 SEND_CHOICES = ( 2 ("register", "注册"), 3 ("forget", "找回密码"), 4 ("update_email", "修改邮箱") 5 ) 6 7 8 #发送邮箱验证码 9 path("sendemail_code/", SendEmailCodeView.as_view(),name='sendemail_code'), 10 11 12# 发送邮箱验证码view 13class SendEmailCodeView(LoginRequiredMixin, View): 14 def get(self,request): 15 # 取出需要发送的邮件 16 email = request.GET.get("email", "") 17 18 # 不能是已注册的邮箱 19 if UserProfile.objects.filter(email=email): 20 return HttpResponse('{"email":"邮箱已经存在"}', content_type='application/json') 21 send_register_eamil(email, "update_email") 22 return HttpResponse('{"status":"success"}', content_type='application/json')

修改utils/email_send.py

1 if send_type == "update_email": 2 email_title = "慕课在线 修改邮箱" 3 email_body = "验证码:{0}".format(code) 4 5 # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list 6 send_status = send_mail(email_title, email_body, EMAIL_FROM, [email]) 7 # 如果发送成功 8 if send_status: 9 pass

修改邮箱

1 #修改邮箱 2 path("update_email/", UpdateEmailView.as_view(),name='update_email'), 3 4 5# 修改邮箱的view: 6class UpdateEmailView(LoginRequiredMixin, View): 7 def post(self, request): 8 email = request.POST.get("email", "") 9 code = request.POST.get("code", "") 10 11 existed_records = EmailVerifyRecord.objects.filter(email=email, code=code, send_type='update_email') 12 if existed_records: 13 user = request.user 14 user.email = email 15 user.save() 16 return HttpResponse('{"status":"success"}', content_type='application/json') 17 else: 18 return HttpResponse('{"email":"验证码无效"}', content_type='application/json')

个人信息修改

1# 个人中心信息修改 2class UserInfoForm(forms.ModelForm): 3 class Meta: 4 model = UserProfile 5 fields = ['nick_name','gender','birthday','address','mobile']

UserinfoView添加post方法

1class UserinfoView(LoginRequiredMixin,View): 2 '''用户个人信息''' 3 def get(self,request): 4 return render(request,'usercenter-info.html',{}) 5 6 def post(self, request): 7 # 需要指明instance。不然无法修改,而是新增用户 8 user_info_form = UserInfoForm(request.POST, instance=request.user) 9 if user_info_form.is_valid(): 10 user_info_form.save() 11 return HttpResponse('{"status":"success"}', content_type='application/json') 12 else: 13 return HttpResponse(json.dumps(user_info_form.errors), content_type='application/json')

我的课程

1# 用户中心我的课程 2path('mycourse/', MyCourseView.as_view(), name="mycourse"), 3 4 5# 个人中心页我的课程 6class MyCourseView(LoginRequiredMixin, View): 7 def get(self, request): 8 user_courses = UserCourse.objects.filter(user=request.user) 9 return render(request, "usercenter-mycourse.html", { 10 "user_courses":user_courses, 11 }) 12 13 14 {% block custom_right_content %} 15 <div class="right" > 16 <div class="personal_des Releasecont"> 17 <div class="head"> 18 <h1>我的课程</h1> 19 </div> 20 </div> 21 <div class="personal_des permessage"> 22 <div class="companycenter"> 23 <div class="group_list brief"> 24 {% for cours in user_courses %} 25 <div class="module1_5 box"> 26 <a href="course-detail.html"> 27 <img width="214" height="190" class="scrollLoading" src="{{ MEDIA_URL }}{{ cours.course.image }}"/> 28 </a> 29 <div class="des"> 30 <a href="course-detail.html"><h2>{{ cours.course.name }}</h2></a> 31 <span class="fl">课时:<i class="key">{{ cours.course.learn_times }}</i></span> 32 <span class="fr">学习人数:{{ cours.course.students }}</span> 33 </div> 34 <div class="bottom"> 35 <span class="fl">{{ cours.course.course_org.name }}</span> 36 <span class="star fr notlogin" data-favid="15">{{ cours.course.course_org.fav_nums }}</span> 37 </div> 38 </div> 39 {% endfor %} 40 </div> 41 </div> 42 </div> 43 </div> 44 {% endblock %}

我的收藏--课程机构

1 # 我的收藏--课程机构 2 path('myfav/org/', MyFavOrgView.as_view(), name="myfav_org"), 3 4 5# 我收藏的课程机构 6class MyFavOrgView(LoginRequiredMixin, View): 7 def get(self, request): 8 org_list = [] 9 fav_orgs= UserFavorite.objects.filter(user=request.user, fav_type=2) 10 # 上面的fav_orgs只是存放了id。我们还需要通过id找到机构对象 11 for fav_org in fav_orgs: 12 # 取出fav_id也就是机构的id。 13 org_id = fav_org.fav_id 14 # 获取这个机构对象 15 org = CourseOrg.objects.get(id=org_id) 16 org_list.append(org) 17 return render(request, "usercenter-fav-org.html", { 18 "org_list": org_list, 19 })

我的收藏--授课讲师

Teacher添加一个方法

1 def get_course_nums(self): 2 return self.course_set.all().count() 3 4 5# 我收藏的授课讲师 6path('myfav/teacher/', MyFavTeacherView.as_view(), name="myfav_teacher"), 7 8 9class MyFavTeacherView(LoginRequiredMixin, View): 10 '''我收藏的授课讲师''' 11 12 def get(self, request): 13 teacher_list = [] 14 fav_teachers = UserFavorite.objects.filter(user=request.user, fav_type=3) 15 for fav_teacher in fav_teachers: 16 teacher_id = fav_teacher.fav_id 17 teacher = Teacher.objects.get(id=teacher_id) 18 teacher_list.append(teacher) 19 return render(request, "usercenter-fav-teacher.html", { 20 "teacher_list": teacher_list, 21 })

我的收藏--公开课程

1 #我的收藏--课程 2 path('myfav/course/', MyFavCourseView.as_view(), name="myfav_course"), 3 4 5class MyFavCourseView(LoginRequiredMixin,View): 6 """ 7 我收藏的课程 8 """ 9 def get(self, request): 10 course_list = [] 11 fav_courses = UserFavorite.objects.filter(user=request.user, fav_type=1) 12 for fav_course in fav_courses: 13 course_id = fav_course.fav_id 14 course = Course.objects.get(id=course_id) 15 course_list.append(course) 16 17 return render(request, 'usercenter-fav-course.html', { 18 "course_list":course_list, 19 })

我的消息页面

1#我的消息 2 path('my_message/', MyMessageView.as_view(), name="my_message"), 3 4 5class MyMessageView(LoginRequiredMixin, View): 6 '''我的消息''' 7 8 def get(self, request): 9 all_message = UserMessage.objects.filter(user= request.user.id) 10 11 try: 12 page = request.GET.get('page', 1) 13 except PageNotAnInteger: 14 page = 1 15 p = Paginator(all_message, 4,request=request) 16 messages = p.page(page) 17 return render(request, "usercenter-message.html", { 18 "messages":messages, 19 })

取消收藏

修改usercenter-bae.html模板中的Ajax代码

修改HTML文件

注册时发生欢迎消息

1# 写入欢迎注册消息 2 user_message = UserMessage() 3 user_message.user = user_profile.id 4 user_message.message = "欢迎注册!!" 5 user_message.save()

页面顶部小喇叭

所有页面都要读取一个共同的变量:未读消息的数量。我们需要向request中注入这个变量 所有页面都有request.user对象。所以我们在userprofile中自定义方法,

1# 获取用户未读消息的数量 2def unread_nums(self): 3 from operation.models import UserMessage 4 return UserMessage.objects.filter(user=self.id).count()

退出

1# 退出功能url 2path('logout/', LogoutView.as_view(), name="logout"), 3 4 5class LogoutView(View): 6 def get(self, request): 7 # django自带的logout 8 logout(request) 9 # 重定向到首页, 10 return HttpResponseRedirect(reverse("index"))

点击数加1

课程 CourseInfoView

1course.students += 1 2course.save()

TeacherDetailView

1teacher.click_nums += 1 2teacher.save()

OrgHomeView

1course_org.click_nums += 1 2course_org.save()

收藏数

organization/views.py中的 AddFavView

1 if exist_records: 2 # 如果记录已经存在, 则表示用户取消收藏 3 exist_records.delete() 4 if int(type) == 1: 5 course = Course.objects.get(id=int(id)) 6 course.fav_nums -= 1 7 if course.fav_nums < 0: 8 course.fav_nums = 0 9 course.save() 10 elif int(type) == 2: 11 org = CourseOrg.objects.get(id=int(id)) 12 org.fav_nums -= 1 13 if org.fav_nums < 0: 14 org.fav_nums = 0 15 org.save() 16 elif int(type) == 3: 17 teacher = Teacher.objects.get(id=int(id)) 18 teacher.fav_nums -= 1 19 if teacher.fav_nums < 0: 20 teacher.fav_nums = 0 21 teacher.save() 22 23 return HttpResponse('{"status":"success", "msg":"收藏"}', content_type='application/json') 24 else: 25 user_fav = UserFavorite() 26 # 过滤掉未取到fav_id type的默认情况 27 if int(type) > 0 and int(id) > 0: 28 user_fav.fav_id = int(id) 29 user_fav.fav_type = int(type) 30 user_fav.user = request.user 31 user_fav.save() 32 if int(type) == 1: 33 course = Course.objects.get(id=int(id)) 34 course.fav_nums += 1 35 course.save() 36 elif int(type) == 2: 37 org = CourseOrg.objects.get(id=int(id)) 38 org.fav_nums += 1 39 org.save() 40 elif int(type) == 3: 41 teacher = Teacher.objects.get(id=int(id)) 42 teacher.fav_nums += 1 43 teacher.save() 44 45 return HttpResponse('{"status":"success", "msg":"已收藏"}', content_type='application/json')

修改消息已读

1class MyMessageView(LoginRequiredMixin, View): 2 '''我的消息''' 3 4 def get(self, request): 5 all_message = UserMessage.objects.filter(user= request.user.id) 6 # 用户进入个人中心消息页面,清空未读消息记录 7 all_unread_messages = all_message.filter(has_read=False) 8 for unread_message in all_unread_messages: 9 unread_message.has_read = True 10 unread_message.save() 11 12 try: 13 page = request.GET.get('page', 1) 14 except PageNotAnInteger: 15 page = 1 16 p = Paginator(all_message, 4, request=request) 17 messages = p.page(page) 18 19 return render(request, "usercenter-message.html", { 20 "messages":messages, 21 })

个人中心左侧active状态

1 <div class="left"> 2 <ul> 3 <li {% ifequal '/users/info/' request.path %} 4 class="active2" 5 {% endifequal %}><a href="{% url 'users:user_info' %}">个人资料</a></li> 6 <li {% ifequal '/users/mycourse/' request.path %} 7 class="active2" 8 {% endifequal %}><a href="{% url 'users:mycourse' %}">我的课程</a></li> 9 <li {% ifequal '/users/myfav/' request.path|slice:'13' %} 10 class="active2" 11 {% endifequal %}><a href="{% url 'users:myfav_org' %}">我的收藏</a></li> 12 <li {% ifequal '/users/my_message/' request.path %} 13 class="active2" 14 {% endifequal %}> 15 <a href="{% url 'users:my_message' %}" style="position: relative;"> 16 我的消息 17 </a> 18 </li> 19 </ul> 20 </div>
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )