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

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

配置全局导航

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

    

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

    

全局搜索功能

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

以Course搜索为例:

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

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

//顶部搜索栏搜索方法
function search_click(){
    var type = $('#jsSelectOption').attr('data-value'),
        keywords = $('#search_keywords').val(),
        request_url = '';
    if(keywords == ""){
        return
    }
    if(type == "course"){
        request_url = "/course/list?keywords="+keywords
    }else if(type == "teacher"){
        request_url = "/org/teacher/list?keywords="+keywords
    }else if(type == "org"){
        request_url = "/org/list?keywords="+keywords
    }
    window.location.href = request_url
}

课程机构搜索功能

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

授课老师搜索功能

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

个人中心信息展示

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

 path("users/", include('users.urls', namespace="users")),
from django.urls import path

from users.views import UserinfoView

app_name = 'users'

urlpatterns = [
    #用户信息
    path("info/", UserinfoView.as_view(),name='user_info'),
]
class UserinfoView(LoginRequiredMixin,View):
    '''用户个人信息'''
    def get(self,request):
        return render(request,'usercenter-info.html',{})

前端显示个人信息

    

个人信息

{% csrf_token %}
  • 昵       称:
  • 生       日:
  • 性       别:
  • 地       址:
  • 手  机  号:
  • 邮       箱: [修改]
{% csrf_token %}

修改密码和修改头像

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

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

# 用于文件上传,修改头像
class UploadImageForm(forms.ModelForm):

    class Meta:
        model = UserProfile
        fields = ['image']
class UploadImageView(LoginRequiredMixin,View):
    '''用户图像修改'''
    def post(self,request):
        # 这时候用户上传的文件就已经被保存到image_form了 ,为modelform添加instance值直接保存
        image_form = UploadImageForm(request.POST, request.FILES, instance=request.user)
        if image_form.is_valid():
            image_form.save()
            # 所有验证通过的字段放在cleaned data
            # # 取出cleaned data中的值,一个dict
            # image = image_form.cleaned_data['image']
            # request.user.image = image
            # request.user.save()
            return HttpResponse('{"status":"success"}', content_type='application/json')
        else:
            return HttpResponse('{"status":"fail"}', content_type='application/json')
#用户个人中心修改密码
    path("update/pwd/", UpdatePwdView.as_view(),name='update_pwd'),
# 在个人中心修改用户密码
class UpdatePwdView(View):
    def post(self, request):
        modiypwd_form = ModifyPwdForm(request.POST)
        if modiypwd_form.is_valid():
            pwd1 = request.POST.get("password1", "")
            pwd2 = request.POST.get("password2", "")
            # 如果两次密码不相等,返回错误信息
            if pwd1 != pwd2:
                return HttpResponse('{"status":"fail", "msg":"密码不一致"}', content_type='application/json')
            # 如果密码一致
            user =request.user
            # 加密成密文
            user.password = make_password(pwd2)
            # save保存到数据库
            user.save()
            return HttpResponse('{"status":"success"}', content_type='application/json')
        # 验证失败说明密码位数不够。
        else:
            return HttpResponse('{"status":"fail", "msg":"填写错误请检查"}', content_type='application/json')

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

发送修改邮箱验证码

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

    SEND_CHOICES = (
        ("register", "注册"),
        ("forget", "找回密码"),
        ("update_email", "修改邮箱")
    )
    #发送邮箱验证码
    path("sendemail_code/", SendEmailCodeView.as_view(),name='sendemail_code'),
# 发送邮箱验证码view
class SendEmailCodeView(LoginRequiredMixin, View):
    def get(self,request):
        # 取出需要发送的邮件
        email = request.GET.get("email", "")

        # 不能是已注册的邮箱
        if UserProfile.objects.filter(email=email):
            return HttpResponse('{"email":"邮箱已经存在"}', content_type='application/json')
        send_register_eamil(email, "update_email")
        return HttpResponse('{"status":"success"}', content_type='application/json')

修改utils/email_send.py

    if send_type == "update_email":
        email_title = "慕课在线 修改邮箱"
        email_body = "验证码:{0}".format(code)

        # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list
        send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
        # 如果发送成功
        if send_status:
            pass

修改邮箱

    #修改邮箱
    path("update_email/", UpdateEmailView.as_view(),name='update_email'),
# 修改邮箱的view:
class UpdateEmailView(LoginRequiredMixin, View):
    def post(self, request):
        email = request.POST.get("email", "")
        code = request.POST.get("code", "")

        existed_records = EmailVerifyRecord.objects.filter(email=email, code=code, send_type='update_email')
        if existed_records:
            user = request.user
            user.email = email
            user.save()
            return HttpResponse('{"status":"success"}', content_type='application/json')
        else:
            return HttpResponse('{"email":"验证码无效"}', content_type='application/json')

个人信息修改

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

UserinfoView添加post方法

class UserinfoView(LoginRequiredMixin,View):
    '''用户个人信息'''
    def get(self,request):
        return render(request,'usercenter-info.html',{})

    def post(self, request):
        # 需要指明instance。不然无法修改,而是新增用户
        user_info_form = UserInfoForm(request.POST, instance=request.user)
        if user_info_form.is_valid():
            user_info_form.save()
            return HttpResponse('{"status":"success"}', content_type='application/json')
        else:
            return HttpResponse(json.dumps(user_info_form.errors), content_type='application/json')

我的课程

# 用户中心我的课程
path('mycourse/', MyCourseView.as_view(), name="mycourse"),
# 个人中心页我的课程
class MyCourseView(LoginRequiredMixin, View):
    def get(self, request):
        user_courses = UserCourse.objects.filter(user=request.user)
        return render(request, "usercenter-mycourse.html", {
            "user_courses":user_courses,
        })
    {% block custom_right_content %}
        

我的课程

{% for cours in user_courses %}

{{ cours.course.name }}

课时:{{ cours.course.learn_times }} 学习人数:{{ cours.course.students }}
{{ cours.course.course_org.name }} {{ cours.course.course_org.fav_nums }}
{% endfor %}
{% endblock %}

我的收藏--课程机构

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

我的收藏--授课讲师

Teacher添加一个方法

    def get_course_nums(self):
        return self.course_set.all().count()
# 我收藏的授课讲师
path('myfav/teacher/', MyFavTeacherView.as_view(), name="myfav_teacher"),
class MyFavTeacherView(LoginRequiredMixin, View):
    '''我收藏的授课讲师'''

    def get(self, request):
        teacher_list = []
        fav_teachers = UserFavorite.objects.filter(user=request.user, fav_type=3)
        for fav_teacher in fav_teachers:
            teacher_id = fav_teacher.fav_id
            teacher = Teacher.objects.get(id=teacher_id)
            teacher_list.append(teacher)
        return render(request, "usercenter-fav-teacher.html", {
            "teacher_list": teacher_list,
        })

我的收藏--公开课程

 #我的收藏--课程
    path('myfav/course/', MyFavCourseView.as_view(), name="myfav_course"),
class MyFavCourseView(LoginRequiredMixin,View):
    """
    我收藏的课程
    """
    def get(self, request):
        course_list = []
        fav_courses = UserFavorite.objects.filter(user=request.user, fav_type=1)
        for fav_course in fav_courses:
            course_id = fav_course.fav_id
            course = Course.objects.get(id=course_id)
            course_list.append(course)

        return render(request, 'usercenter-fav-course.html', {
            "course_list":course_list,
        })

我的消息页面

#我的消息
    path('my_message/', MyMessageView.as_view(), name="my_message"),
class MyMessageView(LoginRequiredMixin, View):
    '''我的消息'''

    def get(self, request):
        all_message = UserMessage.objects.filter(user= request.user.id)

        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(all_message, 4,request=request)
        messages = p.page(page)
        return  render(request, "usercenter-message.html", {
        "messages":messages,
        })

取消收藏

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

QQ截图20180912153830.png

修改HTML文件


QQ截图20180912153939.png

注册时发生欢迎消息

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

页面顶部小喇叭

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

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

退出

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

点击数加1

课程 CourseInfoView

course.students += 1
course.save()

TeacherDetailView

teacher.click_nums += 1
teacher.save()

OrgHomeView

course_org.click_nums += 1
course_org.save()

收藏数

organization/views.py中的 AddFavView

        if exist_records:
            # 如果记录已经存在, 则表示用户取消收藏
            exist_records.delete()
            if int(type) == 1:
                course = Course.objects.get(id=int(id))
                course.fav_nums -= 1
                if course.fav_nums < 0:
                    course.fav_nums = 0
                course.save()
            elif int(type) == 2:
                org = CourseOrg.objects.get(id=int(id))
                org.fav_nums -= 1
                if org.fav_nums < 0:
                    org.fav_nums = 0
                org.save()
            elif int(type) == 3:
                teacher = Teacher.objects.get(id=int(id))
                teacher.fav_nums -= 1
                if teacher.fav_nums < 0:
                    teacher.fav_nums = 0
                teacher.save()

            return HttpResponse('{"status":"success", "msg":"收藏"}', content_type='application/json')
        else:
            user_fav = UserFavorite()
            # 过滤掉未取到fav_id type的默认情况
            if int(type) > 0 and int(id) > 0:
                user_fav.fav_id = int(id)
                user_fav.fav_type = int(type)
                user_fav.user = request.user
                user_fav.save()
                if int(type) == 1:
                    course = Course.objects.get(id=int(id))
                    course.fav_nums += 1
                    course.save()
                elif int(type) == 2:
                    org = CourseOrg.objects.get(id=int(id))
                    org.fav_nums += 1
                    org.save()
                elif int(type) == 3:
                    teacher = Teacher.objects.get(id=int(id))
                    teacher.fav_nums += 1
                    teacher.save()
                    
                return HttpResponse('{"status":"success", "msg":"已收藏"}', content_type='application/json')

修改消息已读

class MyMessageView(LoginRequiredMixin, View):
    '''我的消息'''

    def get(self, request):
        all_message = UserMessage.objects.filter(user= request.user.id)
        # 用户进入个人中心消息页面,清空未读消息记录
        all_unread_messages = all_message.filter(has_read=False)
        for unread_message in all_unread_messages:
            unread_message.has_read = True
            unread_message.save()

        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(all_message, 4, request=request)
        messages = p.page(page)

        return  render(request, "usercenter-message.html", {
            "messages":messages,
        })

个人中心左侧active状态

    

你可能感兴趣的:(Django+Xadmin打造在线教育系统(七))