Django+xadmin打造在线教育平台(八)
代码
十一、用户信息
11.1.个人信息展示
(1)新建‘usercenter-bae.html’当母板
(2)修改‘usercenter-info.html’继承usercenter-bae.html
(3)配置urls
MxOnline/urls.py
#个人信息 path("users/", include('users.urls', namespace="users")),
users/urls.py
from django.urls import path,include,re_path from .views import UserinfoView app_name = 'users' urlpatterns = [ #用户信息 path("info/", UserinfoView.as_view(),name='user_info'), ]
users/views.py
class UserinfoView(LoginRequiredMixin,View): '''用户个人信息''' def get(self,request): return render(request,'usercenter-info.html',{})
然后访问http://127.0.0.1:8000/users/info/ 看看能不能正常显示
(4)显示个人信息
<ul class="right"> <li>昵 称: <input type="text" name="nick_name" id="nick_name" value="{{ request.user.nick_name }}" maxlength="10"> <i class="error-tips"></i> </li> <li>生 日: <input type="text" id="birth_day" name="birday" value="{{ request.user.birthday }}" readonly="readonly"/> <i class="error-tips"></i> </li> <li>性 别: <label> <input type="radio" name="gender" value="male" {% if request.user.gender == 'male' %}checked="checked"{% endif %}>男</label> <label> <input type="radio" name="gender" value="female" {% if request.user.gender == 'female' %}checked="checked"{% endif %}">女</label> </li> <li class="p_infor_city">地 址: <input type="text" name="address" id="address" placeholder="请输入你的地址" value="{{ request.user.adress }}" maxlength="10"> <i class="error-tips"></i> </li> <li>手 机 号: <input type="text" name="mobile" id="mobile" placeholder="请输入你的手机号码" value="{{ request.user.mobile|default_if_none:'' }}" maxlength="10"> </li> <li>邮 箱: <input class="borderno" type="text" name="email" readonly="readonly" value="{{ request.user.email }}"/> <span class="green changeemai_btn">[修改]</span> </li> <li class="button heibtn"> <input type="button" id="jsEditUserBtn" value="保存"> </li> </ul>
说明:
{{ request.user.mobile|default_if_none:'' }} 如果字段没有值,值默认为空字符串
11.2.修改用户图像
(1)url
#用户图像上传 path("image/upload", UploadImageView.as_view(),name='image_upload'),
(2)urers/forms.py
class UploadImageForm(forms.ModelForm): '''用户更改图像''' class Meta: model = UserProfile fields = ['image']
(3)views.py
class UploadImageView(LoginRequiredMixin,View): '''用户图像修改''' def post(self,request): #上传的文件都在request.FILES里面获取,所以这里要多传一个这个参数 image_form = UploadImageForm(request.POST,request.FILES) if image_form.is_valid(): 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')
(4)前端页面
<iframe id='frameFile' name='frameFile' style='display: none;'></iframe>
<form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="{% url 'users:image_upload' %}" target='frameFile'> <label class="changearea" for="avatarUp"> <span id="avatardiv" class="pic"> <img width="100" height="100" class="js-img-show" id="avatarShow" src="{{ MEDIA_URL }}{{ request.user.image }}"/> </span> <span class="fl upload-inp-box" style="margin-left:70px;"> <span class="button btn-green btn-w100" id="jsAvatarBtn">修改头像</span> <input type="file" name="image" id="avatarUp" class="js-img-up"/> </span> </label> <input type='hidden' name='csrfmiddlewaretoken' value='799Y6iPeEDNSGvrTu3noBrO4MBLv6enY' /> {% csrf_token %} </form>
11.3.修改密码
(1)urls
#用户个人中心修改密码 path("update/pwd/", UpdatePwdView.as_view(),name='update_pwd'),
(2)后台处理
class UpdatePwdView(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('{"status":"fail","msg":"密码不一致"}', content_type='application/json') user = request.user user.password = make_password(pwd2) user.save() return HttpResponse('{"status":"success"}', content_type='application/json') else: return HttpResponse(json.dumps(modify_form.errors), content_type='application/json')
(3)Ajxa代码放在deco-user.js里面
$(function(){ //个人资料修改密码 $('#jsUserResetPwd').on('click', function(){ Dml.fun.showDialog('#jsResetDialog', '#jsResetPwdTips'); }); $('#jsResetPwdBtn').click(function(){ $.ajax({ cache: false, type: "POST", dataType:'json', url:"", 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); } } }); });
(4)修改右上角的登录个人状态
base.html
<header> <div class=" header"> <div class="top"> <div class="wp"> <div class="fl"><p>服务电话:<b>33333333</b></p></div> <!--登录后跳转--> {% if request.user.is_authenticated %} <div class="personal"> <dl class="user fr"> <dd>{{ user.username }}<img class="down fr" src="{% static "images/top_down.png" %}"/></dd> <dt><img width="20" height="20" src="{{ MEDIA_URL }}{{ request.user.image }}"/></dt> </dl> <div class="userdetail"> <dl> <dt><img width="80" height="80" src="{{ MEDIA_URL }}{{ request.user.image }}"/></dt> <dd> <h2>{{ request.user.nick_name }}</h2> <p>{{ request.user.username }}</p> </dd> </dl> <div class="btn"> <a class="personcenter fl" href="{% url 'users:user_info' %}">进入个人中心</a> <a class="fr" href="{% url 'logout' %}">退出</a> </div> </div> </div> {% else %} <a style="color:white" class="fr registerbtn" href="{% url 'register' %}">注册</a> <a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登录</a> {% endif %} </div> </div>
同样的把org_base.html和user-center.html也修改一下
11.4.发送邮箱验证码
(1)EmailVerifyRecord Models
- 添加一个choices
- 把send_type的max_length改为30
send_choices = ( ('register','注册'), ('forget','找回密码'), ('update_email','修改邮箱') )
(2)url
#发送邮箱验证码 path("sendemail_code/", SendEmailCodeView.as_view(),name='sendemail_code'),
(3)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')
(4)urils/email_send.py
- 添加一个send_type update_email
- update_email的验证码长度为4
(4)Ajax
Ajax代码在dec-user.js里面
//修改个人中心邮箱验证码 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:"/users/sendemail_code/", 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"); } }); }
测试:
11.5.修改邮箱
(1)urls
#修改邮箱 path("update_email/", UpdateEmailView.as_view(),name='update_email'),
(2)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')
(3)Ajax
//个人资料邮箱修改 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:"/users/update_email/ ", 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"); } }); }
11.6.个人信息修改
(1)users/form.py
class UserInfoForm(forms.ModelForm): '''个人中心信息修改''' class Meta: model = UserProfile fields = ['nick_name','gender','birthday','address','mobile']
(2)view
class UserinfoView(LoginRequiredMixin,View): '''用户个人信息''' def get(self,request): return render(request,'usercenter-info.html') def post(self, request): 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')
11.7.我的课程
(1)url
#我的课程 path("mycourse/", MyCourseView.as_view(),name='mycourse'),
(2)view
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, })
(3)usercenter-mucoure.html
{% extends 'usercenter-base.html' %} {% block title %} 我的课程 {% endblock %} {% block custom_bread %} <section> <div class="wp"> <ul class="crumbs"> <li><a href="{% url 'index' %}">首页</a>></li> <li><a href="/user/home/">个人中心</a>></li> <li>我的课程</li> </ul> </div> </section> {% endblock %} {% block custom_right_content %} <div class="right" > <div class="personal_des Releasecont"> <div class="head"> <h1>我的课程</h1> </div> </div> <div class="personal_des permessage"> <div class="companycenter"> <div class="group_list brief"> {% for user_course in user_courses %} <div class="module1_5 box"> <a href="{% url 'course:course_detail' user_course.course.id %}"> <img width="214" height="190" class="scrollLoading" src="{{ MEDIA_URL }}{{ user_course.course.image }}"/> </a> <div class="des"> <a href="course-detail.html"><h2>{{ user_course.course.name }}</h2></a> <span class="fl">课时:<i class="key">{{ user_course.course.learn_times }}</i></span> <span class="fr">学习人数:{{ user_course.course.students }}</span> </div> <div class="bottom"> <span class="fl">{{ user_course.course.course_org.name }}</span> <span class="star fr notlogin" data-favid="15">{{ user_course.course.fav_nums }}</span> </div> </div> {% endfor %} </div> </div> </div> </div> {% endblock %}
11.8.我的收藏--课程机构
(1)url
# 我的收藏--课程机构 path('myfav/org/', MyFavOrgView.as_view(), name="myfav_org"),
(2)view
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, })
(3)模板usercenter-fav-org.html
{% extends 'usercenter-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="/user/home/">个人中心</a>></li> <li>我的收藏</li> </ul> </div> </section> {% endblock %} {% block custom_right_content %} <div class="right" > <div class="personal_des Releasecont"> <div class="head"> <h1>我的收藏</h1> </div> </div> <div class="personal_des permessage"> <div class="head"> <ul class="tab_header messagehead"> <li class="active"><a href="usercenter-fav-course.html">课程机构</a> </li> <li><a href="usercenter-fav-teacher.html">授课教师 </a></li> <li><a href="usercenter-fav-course.html">公开课程</a></li> </ul> </div> <div class="messagelist"> {% for org in org_list %} <div class="messages butler_list company company-fav-box"> <dl class="des fr"> <dt> <a href="{% url 'org:org_home' org.id %}"> <img width="160" height="90" src="{{ MEDIA_URL }}{{ org.image }}"/> </a> </dt> <dd> <h1><a href="org-detail-homepage.html">{{ org.name }}</a></h1> <div class="pic fl" style="width:auto;"> <img src="{% static 'images/authentication.png' %}"/> <img src="{% static 'images/gold.png' %}"/> </div> <span class="c8 clear">{{ org.address }}</span> <div class="delete jsDeleteFav_org" data-favid="{{org.id}}"></div> </dd> </dl> </div> {% endfor %} </div> </div> </div> {% endblock %}
11.9.我的收藏--授课讲师
Teacher添加一个方法
def get_course_nums(self): return self.course_set.all().count()
url,view和模板
# 我的收藏--授课讲师 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, })
{% extends 'usercenter-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="/user/home/">个人中心</a>></li> <li>我的收藏</li> </ul> </div> </section> {% endblock %} {% block custom_right_content %} <div class="right" > <div class="personal_des Releasecont"> <div class="head"> <h1>我的收藏</h1> </div> </div> <div class="personal_des permessage"> <div class="head"> <ul class="tab_header messagehead"> <li ><a href="{% url 'users:myfav_org' %}">课程机构</a> </li> <li class="active"><a href="{% url 'users:myfav_teacher' %}">授课教师 </a></li> <li><a href="usercenter-fav-course.html">公开课程</a></li> </ul> </div> <div class="messagelist"> {% for teacher in teacher_list %} <div class=" butler_list butler-fav-box"> <dl class="des users"> <dt> <a href="{% url 'org:teacher_detail' teacher.id %}"> <img width="100" height="100" src="{{ MEDIA_URL }}{{ teacher.image }}"/> </a> </dt> <dd> <h1> <a href="{% url 'org:teacher_detail' teacher.id %}"> {{ teacher.name }}<span class="key">认证教师</span> </a> </h1> <ul class="cont clearfix"> <li class="time">工作年限:<span>{{ teacher.work_years }}年</span></li> <li class="c7">课程数:<span>{{ teacher.get_course_nums }}</span></li> </ul> <ul class="cont clearfix"> <li class="time">工作公司:<span>{{ teacher.work_company }}</span></li> <li class="c7">公司职位:<span>{{ teacher.work_position }}</span></li> </ul> </dd> <div class="delete jsDeleteFav_teacher" data-favid="{{teacher.id}}"></div> </dl> </div> {% endfor %} </div> </div> </div> {% endblock %}
11.10.我的收藏--公开课程
#我的收藏--课程 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, })
{% extends 'usercenter-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="/user/home/">个人中心</a>></li> <li>我的收藏</li> </ul> </div> </section> {% endblock %} {% block custom_right_content %} <div class="right" > <div class="personal_des Releasecont"> <div class="head"> <h1>我的收藏</h1> </div> </div> <div class="personal_des permessage"> <div class="head"> <ul class="tab_header messagehead"> <li ><a href="{% url 'users:myfav_org' %}">课程机构</a> </li> <li ><a href="{% url 'users:myfav_teacher' %}">授课教师 </a></li> <li class="active"><a href="{% url 'users:myfav_course' %}">公开课程</a></li> </ul> </div> <div class="companycenter"> <div class="group_list brief"> {% for fav_course in course_list %} <div class="module1_5 box"> <a href="{% url 'course:course_detail' fav_course.id %}"> <img width="214" height="190" src="{{ MEDIA_URL }}{{ fav_course.image }}"/> </a> <div class="des"> <a href="{% url 'course:course_detail' fav_course.id %}"><h2>{{ fav_course.name }}</h2></a> <span class="fl">时长:<i class="key">{{ fav_course.learn_times }}</i></span> <span class="fr">学习人数:{{ fav_course.students }}</span> </div> <div class="bottom"> <span class="fl">{{ fav_course.course_org.name }}</span> <span class="delete-group fr jsDeleteFav_course" data-favid="{{fav_course.id}}"></span> </div> </div> {% endfor %} </div> </div> </div> </div> {% endblock %}
11.11.我的消息
(1)url
#我的消息 path('my_message/', MyMessageView.as_view(), name="my_message"),
(2)view
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, })
(3)模板 usercenter-message.html
{% extends 'usercenter-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="/user/home/">个人中心</a>></li> <li>我的消息</li> </ul> </div> </section> {% endblock %} {% block custom_right_content %} <div class="right" > <div class="personal_des Releasecont"> <div class="head"> <h1>我的消息</h1> </div> </div> <div class="personal_des permessage"> <div class="head"> <ul class="tab_header messagehead"> <li class="active"><a href="/user/message/">个人消息</a> </li> </ul> </div> <div class="messagelist"> {% for message in messages.object_list %} <div class="messages"> <div class="fr"> <div class="top"><span class="fl time">{{ message.add_time }}</span><span class="fr btn foldbtn"></span></div> <p> {{ message.message }} </p> </div> </div> {% endfor %} </div> <div class="pageturn pagerright"> <ul class="pagelist"> {% if messages.has_previous %} <li class="long"><a href="?{{ messages.previous_page_number.querystring }}">上一页</a></li> {% endif %} {% for page in messages.pages %} {% if page %} {% ifequal page messages.number %} <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li> {% else %} <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li> {% endifequal %} {% else %} <li class="none"><a href="">...</a></li> {% endif %} {% endfor %} {% if messages.has_next %} <li class="long"><a href="?{{ messages.next_page_number.querystring }}">下一页</a></li> {% endif %} </ul> </div> </div> </div> {% endblock %}
11.12.logout
(1)url
path('logout/', LogoutView.as_view(), name="logout"),
(2)view
class LogoutView(View): '''用户登出''' def get(self,request): logout(request) from django.urls import reverse return HttpResponseRedirect(reverse('index'))
(3)在每个base页面添加链接
<a class="fr" href="{% url 'logout' %}">退出</a>
11.13.点击数
(1)课程 CourseInfoView
course.students += 1 course.save()
(2)TeacherDetailView
teacher.click_nums += 1 teacher.save()
(3)OrgHomeView
course_org.click_nums += 1 course_org.save()
11.14.收藏数
organization/views.py中的 AddFavView
减的时候
exist_record.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()
加的时候
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()