博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
chapter 10
阅读量:2344 次
发布时间:2019-05-10

本文共 21775 字,大约阅读时间需要 72 分钟。

目录




10.1 完善首页

    1、直接从,网页链接中获取信息

前端代码:

{% if request.path|slice:'9' == '/org/list' %}class="active"{% endif %}
代码解释: request.path 取得当前网页的路径(没有域名的路径  如http://127.0.0.1:8000/org/home/2/ request.path结果为 /org/home/2/  )
slice:'9' == '/org/list' 相当于re正则表达式 ,取前几位然后进行对比
{% if request.path == '/' %}class="active"{% endif %}>首页
  • 公开课
  • 授课教师
  • 授课机构
  • 10.2 完善页头搜索功能

    Django models 对数据库的操作  

    后台代码(对课程进行搜索)

    course.CourseListView()

    class CourseList(View):    def get(self,request):        all_courses = Course.objects.all().order_by("-add_time")        hot_courses = Course.objects.all().order_by("-click_nums")[:3]        #完成搜索功能        search_keywords = request.GET.get('keywords','')        if search_keywords:            all_courses = all_courses.filter(Q(name__icontains= search_keywords)|Q(desc__icontains=search_keywords)|Q(detail__icontains=search_keywords))#name__icontains contains前面的i表示不区分大小写        #课程排序        sort = request.GET.get('sort','')        if sort:            if sort == 'hot':                all_courses = all_courses.order_by('-click_nums')            elif sort == 'students':                all_courses = all_courses.order_by('-student')        try:            page = int(request.GET.get('page', 1))#这里要做一下int转换,这里的request.GET.get('page', 1)中的page是Django在分页时自动生成的        except PageNotAnInteger:            page = 1        paginator = Paginator(all_courses,6,request=request)#每页显示条数3        courses = paginator.page(page)        if request.user.is_authenticated:            username = request.user        else:            username = '未登录,请点击登陆'        return render(request,'course-list.html',{            'all_courses': courses,            'sort':sort,            'hot_courses':hot_courses,            'username':username,        })

    重点在这里,对于课程,老师,机构都是这样写

    search_keywords = request.GET.get('keywords','')        if search_keywords:            all_courses = all_courses.filter(Q(name__icontains= search_keywords)|Q(desc__icontains=search_keywords)|Q(detail__icontains=search_keywords))#name__icontains contains前面的i表示不区分大小写

    前端代码:

    在base.html 页面添加监听代码

    function search_click(){    var type = $('#jsSelectOption').attr('data-value'),//拿到前端数据类型        keywords = $('#search_keywords').val(),   //keywords 这个字段会传到后台,在后台进行查询,他的功能是拿到搜索框中用户输入的内容        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}

    10.3、个人中心

              在所有用户中心页面配置时,在views.py中都要就继承LoginRequiredMixin,以判断用户是否登陆

    1、userinfo 页面配置

          首先先将 user_base页面进行配置,然后在userinfo.html页面中继承base页面,最后将后台数据传到前端

    前端代码 用户信息直接从request.user 传值

    值得注意的是:value="{

    { request.user.mobile|default_if_none:'' }} 后面的default_if_not是对手机号进行判断,如果为空那么将不填充,否则会填充上None

  • 手  机  号:
  • 10.4 、上传用户头像,修改用户信息

    users.views.py

    class UploadImgView(LoginRequiredMixin,View):    def post(self,request):        image_form = UploadImgForm(request.POST,request.FILES)#image是文件类型,不是字段所以后面要加上request.FILES        if image_form.is_valid():            '''            当前端上传图片的时候,如果前端拿到图片,那么clrarned_data里面变回存放前端验证通过的数据            而且数据的字段名称与前端的标签的属性名称一致            '''            img = image_form.cleaned_data['image']  #            request.user.image = img            request.user.save()
    class UploadImgView(LoginRequiredMixin,View):'''           UploadImgForm(request.POST)是前端form传递到 后台的数据            request.FILES 是签单传递的数据类型为file,不再是字段了(默认是字段)            instance=request.user        '''    image_form = UploadImgForm(request.POST,request.FILES,instance=request.user)        if image_form.is_valid():            image_form.save()            return                     HttpResponse(json.dump('{"status":"success"}'),content_type='application/json')        else:            return HttpResponse(json.dump('{"status":"fail"}'),     content_type='application/json')

    10.5 修改用户密码

    后台:

    class ResetPwdView(View):    def post(self,request):        modify_form = ModifyPwdForm(request.POST)        if modify_form.is_valid():            pwd1 = request.POST.get('password1','')            pwd2 = request.POST.get('password2','')            if pwd1 != pwd2:                return HttpResponse(json.dumps('{"status":"fail","msg":"两次密码不一致,请重新输入"}'),content_type='application/json')            else:                user = request.user                user.password = make_password(pwd1)                user.save()                return HttpResponse(json.dumps('{"status":"success"}'), content_type='application/json')        else:            return HttpResponse(json.dumps(modify_form.errors),content_type='application/json')
    path('reset_pwd/',ResetPwdView.as_view(),name = "reset_pwd"),

    前端:

    $(function(){    //个人资料修改密码    $('#jsUserResetPwd').on('click', function(){        Dml.fun.showDialog('#jsResetDialog', '#jsResetPwdTips');    });    $('#jsResetPwdBtn').click(function(){        $.ajax({            cache: false,            type: "POST",            dataType:'json',            url:"/index/reset_pwd/",            data:$('#jsResetPwdForm').serialize(),            async: true,            success: function(data) {                if(data.password1){                    Dml.fun.showValidateError($("#pwd"), data.password1);                }else if(data.password2){                    Dml.fun.showValidateError($("#repwd"), data.password2);                }else if(data.status == "success"){                    Dml.fun.showTipsDialog({                        title:'提交成功',                        h2:'修改密码成功,请重新登录!',                    });                    Dml.fun.winReload();                }else if(data.msg){                    Dml.fun.showValidateError($("#pwd"), data.msg);                    Dml.fun.showValidateError($("#repwd"), data.msg);                }            }        });    });    //个人资料头像    $('.js-img-up').uploadPreview({ Img: ".js-img-show", Width: 94, Height: 94 ,Callback:function(){        $('#jsAvatarForm').submit();    }});    $('.changeemai_btn').click(function(){        Dml.fun.showDialog('#jsChangeEmailDialog', '#jsChangePhoneTips' ,'jsChangeEmailTips');    });    $('#jsChangeEmailCodeBtn').on('click', function(){        sendCodeChangeEmail($(this));    });    $('#jsChangeEmailBtn').on('click', function(){        changeEmailSubmit($(this));    });    //input获得焦点样式    $('.perinform input[type=text]').focus(function(){        $(this).parent('li').addClass('focus');    });    $('.perinform input[type=text]').blur(function(){        $(this).parent('li').removeClass('focus');    });    laydate({        elem: '#birth_day',        format: 'YYYY-MM-DD',        max: laydate.now()    });    verify(        [            {id: '#nick_name', tips: Dml.Msg.epNickName, require: true}        ]    );    //保存个人资料    $('#jsEditUserBtn').on('click', function(){        var _self = $(this),            $jsEditUserForm = $('#jsEditUserForm')            verify = verifySubmit(            [                {id: '#nick_name', tips: Dml.Msg.epNickName, require: true}            ]        );        if(!verify){           return;        }        $.ajax({            cache: false,            type: 'post',            dataType:'json',            url:"/users/info/",            data:$jsEditUserForm.serialize(),            async: true,            beforeSend:function(XMLHttpRequest){                _self.val("保存中...");                _self.attr('disabled',true);            },            success: function(data) {                if(data.nick_name){                    _showValidateError($('#nick_name'), data.nick_name);                }else if(data.birday){                   _showValidateError($('#birth_day'), data.birday);                }else if(data.address){                   _showValidateError($('#address'), data.address);                }else if(data.status == "failure"){                     Dml.fun.showTipsDialog({                        title: '保存失败',                        h2: data.msg                    });                }else if(data.status == "success"){                    Dml.fun.showTipsDialog({                        title: '保存成功',                        h2: '个人信息修改成功!'                    });                    setTimeout(function(){window.location.href = window.location.href;},1500);                }            },            complete: function(XMLHttpRequest){                _self.val("保存");                _self.removeAttr("disabled");            }        });    });});

    未解决的问题,

    当密码符合但不一致是,不能给提示

    未验证旧密码

    密码修改成功后转到登陆页面,但是不能自动刷新,要将当前个人信息页面刷新才可以进入登录页面

     

    10.6 修改用户邮箱,并对邮箱进行验证

    后台代码:

    sittings.py: 主要是设置邮箱的相关信息,如密码,主发邮箱号

    EMAIL_HOST = 'smtp.qq.com'EMAIL_POSRT = 25EMAIL_HOST_USER = "1194380923@qq.com"#邮箱名EMAIL_HOST_PASSWORD = "xpkdjgkhhwvbgjce"#密码,这里要换成授权码EMAIL_USE_TLS = FalseEMAIL_FROM = "1194380923@qq.com"#邮箱名

    users.email_send.py

    这是一个可供其他方法调用的发送邮箱的方法,不能和视屏一样放在utils里面,会出错(为什么我也不知道)

    import randomfrom django.core.mail import send_mailfrom .models import EmailVerifyRecordfrom MXonline.settings import EMAIL_FROMdef send_register_email(email,send_type="register"):#参数含义:email将要发送的邮箱地址,type发送邮件的当下情    email_record = EmailVerifyRecord()    code = random_str()#随机验证码    email_record.code = code    email_record.email = email    email_record.send_type = send_type    email_record.save()#将邮箱验证的信息(邮箱号,验证码,验证类型)存入到数据库,为之后用户填写验证码后台做验证的时候使用    #定义邮件内容    email_title = ""    email_body = ""    if send_type == "register":        email_title = "激活链接"        email_body = "请点击下面的激活链接:http://127.0.0.1:8000/index/active/"+str(code)        send_status =  send_mail(email_title,email_body,EMAIL_FROM,[email])        if send_status:            pass    elif send_type == "forget":        email_title = "密码重置链接"        email_body = "请点击下面的密码重置链接:http://127.0.0.1:8000/index/reset/"+str(code)        send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])        if send_status:            pass    if send_type == "update":        email_title = "重置邮箱激活验证码"        email_body = "你的邮箱激活验证码为:{0}".format(code)        send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])        if send_status:            passdef random_str():    number = random.randint(100000,999999)    string = str(number)    return string

    users.views

    class ResetEmailView(View):    '''    发送邮箱验证码    '''    def get(self,request):        email = request.GET.get('email','')        if UserProfile.objects.filter(email= email):            return HttpResponse(json.dumps('{"email":"邮箱已存在"}'),content_type='application/json')        send_register_email(email,'update')        return HttpResponse(json.dumps('{"status":"success"}'),content_type='application/json')class EmailVerifyView(LoginRequiredMixin, View):    def post(self, request):        email = request.POST.get('email','')        code = request.POST.get('code','')        if EmailVerifyRecord.objects.filter(email = email,code=code, send_type = 'update'):#从数据库查询到当时发送邮件所保存的信息            user = request.user            user.email = email            user.save()            return HttpResponse(json.dumps('{"status":"success"}'),content_type='application/json')        else:            return HttpResponse(json.dumps('{"email":"验证码出错"}'), content_type='application/json')

    users.uels.py

    path('reset_email/',ResetEmailView.as_view(),name = "reset_email"),    path('send_emailcode/',EmailVerifyView.as_view(),name = "send_emailcode"),

     

     

    前端代码

    HTML代码

    修改邮箱

    请输入新的邮箱地址

    请输入...
    {% csrf_token %}

     

    js代码  ajax 看不懂,勉强能读

    //修改个人中心邮箱验证码function sendCodeChangeEmail($btn){    var verify = verifyDialogSubmit(        [          {id: '#jsChangeEmail', tips: Dml.Msg.epMail, errorTips: Dml.Msg.erMail, regName: 'email', require: true}        ]    );    if(!verify){       return;    }    $.ajax({        cache: false,        type: "get",        dataType:'json',        url:"/index/reset_email/",        data:$('#jsChangeEmailForm').serialize(),        async: true,        beforeSend:function(XMLHttpRequest){            $btn.val("发送中...");            $btn.attr('disabled',true);        },        success: function(data){            if(data.email){                Dml.fun.showValidateError($('#jsChangeEmail'), data.email);            }else if(data.status == 'success'){                Dml.fun.showErrorTips($('#jsChangeEmailTips'), "邮箱验证码已发送");            }else if(data.status == 'failure'){                 Dml.fun.showValidateError($('#jsChangeEmail'), "邮箱验证码发送失败");            }else if(data.status == 'success'){            }        },        complete: function(XMLHttpRequest){            $btn.val("获取验证码");            $btn.removeAttr("disabled");        }    });}//个人资料邮箱修改function changeEmailSubmit($btn){var verify = verifyDialogSubmit(        [          {id: '#jsChangeEmail', tips: Dml.Msg.epMail, errorTips: Dml.Msg.erMail, regName: 'email', require: true},        ]    );    if(!verify){       return;    }    $.ajax({        cache: false,        type: 'post',        dataType:'json',        url:"/index/send_emailcode/",        data:$('#jsChangeEmailForm').serialize(),        async: true,        beforeSend:function(XMLHttpRequest){            $btn.val("发送中...");            $btn.attr('disabled',true);            $("#jsChangeEmailTips").html("验证中...").show(500);        },        success: function(data) {            if(data.email){                Dml.fun.showValidateError($('#jsChangeEmail'), data.email);            }else if(data.status == "success"){                Dml.fun.showErrorTips($('#jsChangePhoneTips'), "邮箱信息更新成功");                setTimeout(function(){location.reload();},1000);            }else{                 Dml.fun.showValidateError($('#jsChangeEmail'), "邮箱信息更新失败");            }        },        complete: function(XMLHttpRequest){            $btn.val("完成");            $btn.removeAttr("disabled");        }    });}

    10.7 修改用户基本信息(手机号,用户名,生日,地址,性别)

    后台代码:

    user.forms.py

    class UserInfoForm(forms.ModelForm):    class Meta:        model = UserProfile        fields = ['username','birthday','mobile','gender','address']

    user.views.py

    class ResetUserInfoView(LoginRequiredMixin,View):    def post(self,request):        '''        因为UserInfoForm是继承ModelForm的form,所以user_info可以像model那样直接保存前端的数据到数据库        '''        user_info = UserInfoForm(request.POST,instance=request.user)#后面的request.user很重要,不知道为什么        if user_info.is_valid():            user_info.save()            return HttpResponse(json.dumps('{"status":"success"}'),content_type='application/json')        else:            return HttpResponse(json.dumps(user_info.errors),content_type='application/json')

    前端数据:

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

    js 代码

    $('#jsEditUserBtn').on('click', function(){        var _self = $(this),            $jsEditUserForm = $('#jsEditUserForm')            verify = verifySubmit(            [                {id: '#nick_name', tips: Dml.Msg.epNickName, require: true}            ]        );        if(!verify){           return;        }// debugger        $.ajax({            cache: false,            type: 'post',            dataType:'json',            url:"/index/info/",            data:$jsEditUserForm.serialize(),            async: true,            beforeSend:function(XMLHttpRequest){                _self.val("保存中...");                _self.attr('disabled',true);            },            success: function(data) {                if(data.username){                    _showValidateError($('#nick_name'), data.username);                }else if(data.birthday){                   _showValidateError($('#birth_day'), data.birthday);                }else if(data.address){                   _showValidateError($('#address'), data.address);                }else if(data.status == "failure"){                     Dml.fun.showTipsDialog({                        title: '保存失败',                        h2: data.msg                    });                }else if(data.status == "success"){                    Dml.fun.showTipsDialog({                        title: '保存成功',                        h2: '个人信息修改成功!'                    });                    setTimeout(function(){window.location.href = window.location.href;},1500);                }            },            complete: function(XMLHttpRequest){                _self.val("保存");                _self.removeAttr("disabled");            }        });    });

    10.8 用户课程

    后台代码:

    class UserCourseView(LoginRequiredMixin,View):    def get(self,request):        usercourses = UserCourse.objects.filter(user = request.user)        return render(request,'usercenter-mycourse.html',{            'usercourses':usercourses,        })

    前端代码:

    {% for course in usercourses %}                                

    {
    { course.course.name }}

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

    10.9配置用户收藏的课程

    后台代码:

    、views.py

    class UserFavCourseView(LoginRequiredMixin,View):    def get(self,request):        fav_courses = UserFavorate.objects.filter(fav_type = 1,user = request.user)        msg = ''        courses = []        if fav_courses:            for fav in fav_courses:                course = Course.objects.get(id = fav.fav_id)                courses.append(course)            return render(request, 'usercenter-fav-course.html', {                'courses': courses,                'msg':msg            })        else:            msg = '该同学没有收藏任何课程'            return render(request,'usercenter-fav-course.html',{                'msg':msg            })class UserFavOrgView(LoginRequiredMixin,View):    def get(self,request):        fav_orgs = UserFavorate.objects.filter(fav_type=2, user=request.user)        msg = ''        orgs = []        if fav_orgs:            for fav in fav_orgs:                org = CourseOrg.objects.get(id=fav.fav_id)                orgs.append(org)            return render(request, 'usercenter-fav-org.html', {                'orgs': orgs,                'msg': msg            })        else:            msg = '该同学没有收藏任何课程机构'            return render(request, 'usercenter-fav-org.html', {                'msg': msg            })class UserFavTeacherView(LoginRequiredMixin,View):    def get(self,request):        fav_teachers = UserFavorate.objects.filter(fav_type=3, user=request.user)        msg = ''        teachers = []        if fav_teachers:            for fav in fav_teachers:                teacher = Teacher.objects.get(id=fav.fav_id)                teachers.append(teacher)            return render(request, 'usercenter-fav-teacher.html', {                'teachers': teachers,                'msg': msg            })        else:            msg = '该同学没有收藏任何老师'            return render(request, 'usercenter-fav-teacher.html', {                'msg': msg            })

    urls.py

    path('user_favcourse/',UserFavCourseView.as_view(),name = "user_favcourse"),    path('user_favorg/',UserFavOrgView.as_view(),name = "user_favorg"),    path('user_favteacher/',UserFavTeacherView.as_view(),name = "user_favteacher"),

    前端:

    和普通的配置一样,注意将所有连接改掉

    10.10删除用户收藏

    前端接js代码

    10.11用户消息配置,及全局显示

    后台页面:

    class UserProfile(AbstractUser):#扩展用户信息数据库    birthday = models.DateTimeField(verbose_name=u"生日", null=True, blank=True, default=None)    nick_name = models.CharField(max_length=30, verbose_name=u"昵称", default=u"")    #birthday = models.DateTimeField(verbose_name=u"生日",null=True,blank=True,default=u"")    gender = models.CharField(choices=(("male",u"男"),("femal",u"女")),default=u"",max_length=6)    address = models.CharField(max_length=100,default=u"")    mobile = models.CharField(max_length=11,blank=True,null=True)    image = models.ImageField(upload_to="image/%Y/%m",default=u"image/default.img",max_length=100)#用户头像和默认头像    class Meta:        verbose_name = u"用户信息"        verbose_name_plural = verbose_name    def __str__(self):#admin 管理时返回的题目标题        return self.username    def unread_message(self):        '''        获取当前用户未读的信息的条数        在当前方法内部 引入外部模块,防止循环引用        '''        from operation.models import UserMessage        message = UserMessage.objects.filter(user = self.id,has_read = False)        return message.count()

    前端代码直接配置到页面

                                
    {
    { request.user.unread_message }}

     

     

     

    转载地址:http://jrnvb.baihongyu.com/

    你可能感兴趣的文章
    如何成为一名合格的Java程序员?
    查看>>
    spring框架中5种自动装配模式介绍
    查看>>
    如何学习Spring框架?有哪些建议?
    查看>>
    Java程序员烂大街了吗?是,也不是
    查看>>
    为什么学编程大部分人选Java编程语言?
    查看>>
    Java学习注意哪些问题?学习少踩坑
    查看>>
    两年Java后端开发,面试了几十家公司的面试分享
    查看>>
    一定要在C++和JAVA中选择,应该学那个好?
    查看>>
    C语言、C++、Java,Python之间的区别,哪个更有前景,哪个更难 ?
    查看>>
    作为大学生,现在学习Java还有出路吗?
    查看>>
    Java的JDK在哪里下载,如何下载?
    查看>>
    985毕业,半路出家28岁进军Java,坚持了三年现如今年薪36W+,也不算辜负自己!
    查看>>
    零基础JAVA和web前端该选哪个好?
    查看>>
    Java大牛学习经验:新手建议按这6步学习 !
    查看>>
    从事程序员的工作,Python大数据、Java、前端,哪个更有发展前景!
    查看>>
    假如我是面试官,我会这样虐你!
    查看>>
    没学历,当程序员还有机会吗?
    查看>>
    Java程序员进阶:Java异常知识点梳理
    查看>>
    Java程序员必备核心知识点整理,建议收藏!
    查看>>
    Java学习顺序流程和学习方法
    查看>>