Django在线教育平台项目完整实现(三)

七、个人中心相关功能开发

1.个人资料显示

将usercenter-fav-course.html、usercenter-fav-org.html、usercenter-fav-teacher.html、usercenter-info.html、usercenter-message.html、usercenter-mycourse.html页面拷贝到templates目录下

并新建一个usercenter-base.html页面

<!DOCTYPE html>
<html>
{% load staticfiles %}
<head>
	<meta charset="UTF-8">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
	<title>{% block title %}个人信息- 慕学在线网{% endblock %}</title>
	<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
	<link rel="stylesheet" type="text/css" href="{% static 'css/animate.css' %}">
	<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'js/plugins/queryCity/css/cityLayout.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/lq.datetimepick.css' %}"/>
    {% block custom_css %}
    {% endblock %}


    <script src="{% static 'js/jquery.min.js' %}" type="text/javascript"></script>
    <script src="{% static 'js/jquery-migrate-1.2.1.min.js' %}" type="text/javascript"></script>

</head>
<body>
<section class="headerwrap headerwrap2">
    <header>
		<div  class="header2 header">
 			<div class="top">
				<div class="wp">
					<div class="fl"><p>服务电话:<b>33333333</b></p></div>
					<!--登录后跳转-->
                        <!--如果用户已经登录-->
                        {% if user.is_authenticated %}

                            <div class="personal">
                                <dl class="user fr">
                                    <dd>{% if user.nick_name %}{{ user.nickname }}{% else %}{{ user.username }}{% endif %}<img class="down fr" src="{% static 'images/top_down.png' %}"/></dd>
                                    <dt><img width="20" height="20" src="{{ user.image.url }}"/></dt>
                                </dl>
                                <div class="userdetail">
                                    <dl>
                                        <dt><img width="80" height="80" src="{{ user.image.url }}"/></dt>
                                        <dd>
                                            <h2>{{ user.nick_name }}</h2>
                                            <p>{{ user.username }}</p>
                                        </dd>
                                    </dl>
                                    <div class="btn">
                                        <a class="personcenter fl" href="{% url 'users: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 %}
                        <a href="usercenter-message.html">
                            <div class="msg-num"><span id="MsgNum">0</span></div>
                        </a>


				</div>
			</div>

    <div class="middle">
        <div class="wp">
            <a href="{% url 'index' %}"><img class="fl" src="{% static 'images/logo2.png' %}"/></a>
            <h1>我的慕学网</h1>
        </div>
    </div>
			</div>
    </header>
</section>



<!--crumbs start-->
{% block custom_bread %}
    <section>
        <div class="wp">
            <ul  class="crumbs">
                <li><a href="index.html">首页</a>></li>
                <li><a href="/user/home/">个人中心</a>></li>
                <li>个人信息</li>
            </ul>
        </div>
    </section>
{% endblock %}
<section>
	<div class="wp list personal_list">
	<div class="left">
        <ul>
            <li class="active2"><a href="usercenter-info.html">个人资料</a></li>
            <li ><a href="usercenter-mycourse.html">我的课程</a></li>
            <li ><a href="usercenter-fav-course.html">我的收藏</a></li>
            <li >
                <a href="usercenter-message.html" style="position: relative;">
                    我的消息
                </a>
            </li>
        </ul>
	</div>

    {% block right_form %}
    <div class="right">
		<div class="personal_des ">
			<div class="head" style="border:1px solid #eaeaea;">
				<h1>个人信息</h1>
			</div>
			<div class="inforcon">
				<div class="left" style="width:242px;">
                    <iframe id='frameFile' name='frameFile' style='display: none;'></iframe>
                    <form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="/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/image/2016/12/default_big_14.png"/>
                            </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>
                    </form>
                    <div style="border-top:1px solid #eaeaea;margin-top:30px;">
                        <a class="button btn-green btn-w100" id="jsUserResetPwd" style="margin:80px auto;width:100px;">修改密码</a>
                    </div>
				</div>
				<form class="perinform" id="jsEditUserForm" autocomplete="off">
					<ul class="right">
						<li>昵       称:
                           <input type="text" name="nick_name" id="nick_name" value="django" maxlength="10">
                            <i class="error-tips"></i>
                        </li>
						<li>生       日:
                           <input type="text" id="birth_day" name="birday" value="2009年9月2日" readonly="readonly"/>
                            <i class="error-tips"></i>
						</li>
						<li>性       别:
							<label>     <input type="radio"  name="gender" value="male" ></label>
							<label>      <input type="radio" name="gender" value="female" checked="checked"></label>
						</li>
						<li class="p_infor_city">地       址:
                            <input type="text" name="address" id="address" placeholder="请输入你的地址" value="我来自火星" maxlength="10">
						    <i class="error-tips"></i>
                        </li>
                        <li>手  机  号:
                            <input class="borderno" type="text" name="mobile" readonly="readonly" value="">
                            <span class="changeemai_btn green changephone-color">[修改]</span>
                        </li>
						<li class="button heibtn">
							<input type="button" id="jsEditUserBtn" value="保存">
						</li>
					</ul>
				</form>
			</div>
		</div>
	</div>
    {% endblock %}


	</div>
</section>


<!--sidebar start-->
<section>
    <ul class="sidebar">
        <li class="qq">
            <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=2023525077&site=qq&menu=yes"></a>
        </li>
        <li class="totop"></li>
    </ul>
</section>
<!--sidebar end-->
<!--header start-->

<div class="dialog" id="jsDialog">
    <div class="successbox dialogbox" id="jsSuccessTips">
        <h1>成功提交</h1>
        <div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div>
        <div class="cont">
            <h2>您的需求提交成功!</h2>
            <p></p>
        </div>
    </div>
    <!--提示弹出框-->
    <div class="bidtips dialogbox promptbox" id="jsComfirmDialig">
        <h1>确认提交</h1>
        <div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div>
        <div class="cont">
            <h2>您确认提交吗?</h2>
            <dd class="autoTxtCount">
                <div class="button">
                    <input type="button" class="fl half-btn" value="确定" id="jsComfirmBtn"/>
                    <span class="fr half-btn jsCloseDialog">取消</span>
                </div>
            </dd>
        </div>
    </div>
    <div class="resetpwdbox dialogbox" id="jsResetDialog">
        <h1>修改密码</h1>
        <div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div>
        <div class="cont">
            <form id="jsResetPwdForm" autocomplete="off">
                <div class="box">
                    <span class="word2" >新  密  码</span>
                    <input type="password" id="pwd" name="password1" placeholder="6-20位非中文字符"/>
                </div>
                <div class="box">
                    <span class="word2" >确定密码</span>
                    <input type="password" id="repwd" name="password2" placeholder="6-20位非中文字符"/>
                </div>
                <div class="error btns" id="jsResetPwdTips"></div>
                <div class="button">
                    <input id="jsResetPwdBtn" type="button" value="提交" />
                </div>
            </form>
        </div>
    </div>

    <!--手机修改-->
    <div class="dialogbox changephone changephone1" id="jsChangePhoneDialog" style="display: none; margin-top: 81px;">
        <h1>修改手机号码</h1>
        <div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"></div>
        <p>请输入新的手机号码</p>
        <form id="jsChangePhoneForm" autocomplete="off">
            <div class="box">
                <input class="fl change_mobile" type="text" id="jsChangePhone" name="mobile" autocomplete="off" placeholder="输入重新绑定的手机号码">
            </div>
            <div class="box">
                <input autocomplete="off" class="form-control-captcha find-password-captcha" id="find-password-captcha_1" name="captcha_1" placeholder="请输入验证码" type="text">
                <input class="form-control-captcha find-password-captcha" id="find-password-captcha_0" name="captcha_0" placeholder="请输入验证码" type="hidden" value="5de5a9903eced0b941df9478f26896879956ca18">
                 <img src="./个人资料_files/saved_resource" alt="captcha" class="captcha">
            </div>
            <div class="box">
                <input class="fl" type="text" id="jsChangePhoneCode" name="mobile_code" placeholder="输入手机验证码">
                <input class="getcode getting" type="button" id="jsChangePhoneCodeBtn" value="获取验证码">
            </div>
            <div class="error btns" id="jsChangePhoneTips" style="display: none;"></div>
            <div class="button">
                <input type="button" value="完成" id="jsChangePhoneBtn">
            </div>

        </form>
    </div>
    <div class="resetpassbox dialogbox" id="jsSetNewPwd">
        <h1>重新设置密码</h1>
        <div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div>
        <p class="green">请输入新密码</p>
        <form id="jsSetNewPwdForm">
            <div class="box">
                <span class="word2">密      码</span>
                <input type="password" name="password" id="jsResetPwd" placeholder="请输入新密码"/>
            </div>
            <div class="box">
                <span class="word2">确 认 密 码</span>
                <input type="password" name="password2" id="jsResetPwd2" placeholder="请再次输入新密码"/>
            </div>
            <div class="box">
                <span class="word2">验  证  码</span>
                <input type="text" name="code" id="jsResetCode" placeholder="请输入手机验证码"/>
            </div>
            <div class="error btns" id="jsSetNewPwdTips"></div>
            <div class="button">
                <input type="hidden" name="mobile" id="jsInpResetMobil" />
                <input id="jsSetNewPwdBtn" type="button" value="提交" />
            </div>
        </form>
    </div>
    <div class="forgetbox dialogbox">
        <h1>忘记密码</h1>
        <div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div>
        <div class="cont">
            <form id="jsFindPwdForm" autocomplete="off">
                <div class="box">
                    <span class="word2" >账      号</span>
                    <input type="text" id="account" name="account" placeholder="手机/邮箱"/>
                </div>
                <div class="box">
                    <span class="word3">验证码</span>
                    <input autocomplete="off" class="form-control-captcha find-password-captcha" id="find-password-captcha_1" name="captcha_f_1" placeholder="请输入验证码" type="text" /> <input class="form-control-captcha find-password-captcha" id="find-password-captcha_0" name="captcha_f_0" placeholder="请输入验证码" type="hidden" value="5f3c00e47fb1be12d2fd15b9a860711597721b3f" />  <img src="/captcha/image/5f3c00e47fb1be12d2fd15b9a860711597721b3f/" alt="captcha" class="captcha" />
                </div>
                <div class="error btns" id="jsForgetTips"></div><!--忘记密码错误-->
                <div class="button">
                    <input type="hidden" name="sms_type" value="1">
                    <input id="jsFindPwdBtn" type="button" value="提交" />
                </div>
            </form>
        </div>
    </div>
</div>
<div class="bg" id="dialogBg"></div>


<script src="{% static 'js/selectUi.js' %}" type='text/javascript'></script>
<script type="text/javascript" src="{% static 'js/plugins/laydate/laydate.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script src="{% static 'js/plugins/queryCity/js/public.js' %}" type="text/javascript"></script>
<script src="{% static 'js/unslider.js' %}" type="text/javascript"></script>
<script src="{% static 'js/plugins/jquery.scrollLoading.js' %}"  type="text/javascript"></script>
<script src="{% static 'js/validateDialog.js' %}"  type="text/javascript"></script>
<script src="{% static 'js/deco-common.js' %}"  type="text/javascript"></script>

<script src='{% static "js/plugins/jquery.upload.js" %}' type='text/javascript'></script>
<script src="{% static 'js/validate.js' %}" type="text/javascript"></script>
<script src="{% static 'js/deco-user.js' %}"></script>

<script type="text/javascript">
    $(document).ready(function() {
        $('.jsDeleteFav_course').on('click', function () {
            var _this = $(this),
                favid = _this.attr('data-favid');
            alert(favid)
            $.ajax({
                cache: false,
                type: "POST",
                url: "/org/add_fav/",
                data: {
                    fav_type: 1,
                    fav_id: favid,
                    csrfmiddlewaretoken: '799Y6iPeEDNSGvrTu3noBrO4MBLv6enY'
                },
                async: true,
                success: function (data) {
                    Dml.fun.winReload();
                }
            });
        });
    });
    $(document).ready(function() {
        $('.jsDeleteFav_teacher').on('click', function () {
            var _this = $(this),
                favid = _this.attr('data-favid');
            $.ajax({
                cache: false,
                type: "POST",
                url: "/org/add_fav/",
                data: {
                    fav_type: 3,
                    fav_id: favid,
                    csrfmiddlewaretoken: '799Y6iPeEDNSGvrTu3noBrO4MBLv6enY'
                },
                async: true,
                success: function (data) {
                    Dml.fun.winReload();
                }
            });
        });
    });

    $(document).ready(function() {
        $('.jsDeleteFav_org').on('click', function () {
            var _this = $(this),
                favid = _this.attr('data-favid');
            $.ajax({
                cache: false,
                type: "POST",
                url: "/org/add_fav/",
                data: {
                    fav_type: 2,
                    fav_id: favid,
                    csrfmiddlewaretoken: '799Y6iPeEDNSGvrTu3noBrO4MBLv6enY'
                },
                async: true,
                success: function (data) {
                    Dml.fun.winReload();
                }
            });
        });
    });
</script>


<script>
        var shareUrl = '',
            shareText = '',
            shareDesc = '',
            shareComment = '';
        $(function () {
            $(".bdsharebuttonbox a").mouseover(function () {
                var type = $(this).attr('data-cmd'),
                    $parent = $(this).parent('.bdsharebuttonbox'),
                    fxurl = $parent.attr('data-url'),
                    fxtext = $parent.attr('data-text'),
                    fxdesc = $parent.attr('data-desc'),
                    fxcomment = $parent.attr('data-comment');
                switch (type){
                    case 'tsina':
                    case 'tqq':
                    case 'renren':
                            shareUrl = fxurl;
                            shareText = fxdesc;
                            shareDesc = '';
                            shareComment = '';
                        break;
                    default :
                            shareUrl = fxurl;
                            shareText = fxtext;
                            shareDesc = fxdesc;
                            shareComment = fxcomment;
                        break;
                }
            });
        });
        function SetShareUrl(cmd, config) {
            if (shareUrl) {
                config.bdUrl = "" + shareUrl;
            }
            if(shareText){
                config.bdText = shareText;
            }
            if(shareDesc){
                config.bdDesc = shareDesc;
            }
            if(shareComment){
                config.bdComment = shareComment;
            }

            return config;
        }
        window._bd_share_config = {
            "common": {
                "onBeforeClick":SetShareUrl,
                "bdPic":"",
                "bdMini":"2",
                "searchPic":"1",
                "bdMiniList":false
            },
            "share": {
                "bdSize":"16"
            }
        };
    with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com../api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
{% block custom_js %}
{% endblock %}
</body>
</html>

将templates/usercenter-info.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="{% url 'users:info' %}">个人中心</a>></li>
                <li>个人信息</li>
            </ul>
        </div>
    </section>
{% endblock %}

{% block right_form %}

    <div class="right">
		<div class="personal_des ">
			<div class="head" style="border:1px solid #eaeaea;">
				<h1>个人信息</h1>
			</div>
			<div class="inforcon">
				<div class="left" style="width:242px;">
                    <iframe id='frameFile' name='frameFile' style='display: none;'></iframe>
                    <form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="/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="{{ user.image.url }}"/>
                            </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>
                    </form>
                    <div style="border-top:1px solid #eaeaea;margin-top:30px;">
                        <a class="button btn-green btn-w100" id="jsUserResetPwd" style="margin:80px auto;width:100px;">修改密码</a>
                    </div>
				</div>
				<form class="perinform" id="jsEditUserForm" autocomplete="off">
					<ul class="right">
						<li>昵       称:
                            <!-- 若没有nick_name传递一个空字符串,不然会显示None -->
                           <input type="text" name="nick_name" id="nick_name" value="{{ user.nick_name|default_if_none:'' }}" maxlength="10">
                            <i class="error-tips"></i>
                        </li>
						<li>生       日:
                            <!-- 将日期进行格式化,否则进行修改保存时,服务器无法识别 -->
                           <input type="text" id="birth_day" name="birthday" value="{{ user.birthday|default_if_none:''|date:'Y-m-d' }}" readonly="readonly"/>
                            <i class="error-tips"></i>
						</li>
						<li>性       别:
							<label>     <input type="radio"  name="gender" value="male" {% if user.gender == 'male' %}checked="checked"{% endif %}>男</label>
							<label>      <input type="radio" name="gender" value="female" {% if user.gender == 'female' %}checked="checked"{% endif %}>女</label>
						</li>
						<li class="p_infor_city">地       址:
                            <input type="text" name="address" id="address" placeholder="请输入你的地址" value="{{ user.address }}" maxlength="10">
						    <i class="error-tips"></i>
                        </li>
                        <li>手  机  号:
                            <input class="borderno" type="text" name="mobile" readonly="readonly" value="{{ user.mobile }}">
                            <span class="changeemai_btn green changephone-color">[修改]</span>
                        </li>
						<li class="button heibtn">
							<input type="button" id="jsEditUserBtn" value="保存">
						</li>
					</ul>
				</form>
			</div>
		</div>
	</div>

{% endblock %}

在MxOnline/urls.py中:

# 省略
urlpatterns = [
    # 省略

    # 用户相关操作
    url(r'^op/', include(('apps.operations.urls', "operations"), namespace="op")),

    # 个人中心
    url(r'^users/', include(('apps.users.urls', "users"), namespace="users")),

]

在apps/users/views.py中:

import redis
from django.contrib.auth.mixins import LoginRequiredMixin

from apps.users.forms import LoginForm, DynamicLoginForm, DynamicLoginPostForm
from apps.users.forms import RegisterGetForm, RegisterPostForm
from apps.utils.YunPian import send_single_sms
from apps.utils.random_str import generate_random
from MxOnline.settings import yp_apikey, REDIS_HOST, REDIS_PORT
from apps.users.models import UserProfile


# Create your views here.

# 用户信息
class UserInfoView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        return render(request, "usercenter-info.html"

在apps/users文件夹下新建一个urls.py

from django.conf.urls import url

from apps.users.views import UserInfoView



urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),

]

更改跳转链接:
在templates/base.html中(27行)和templates/org_base.html中(28行)和templates/index.html(27行):

<!--如果用户已经登录-->
{% if user.is_authenticated %}

    <div class="personal">
        <dl class="user fr">
            <dd>{% if user.nick_name %}{{ user.nickname }}{% else %}{{ user.username }}{% endif %}<img class="down fr" src="{% static 'images/top_down.png' %}"/></dd>
            <dt><img width="20" height="20" src="{{ user.image.url }}"/></dt>
        </dl>
        <div class="userdetail">
            <dl>
                <dt><img width="80" height="80" src="{{ user.image.url }}"/></dt>
                <dd>
                    <h2>{{ user.nick_name }}</h2>
                    <p>{{ user.username }}</p>
                </dd>
            </dl>
            <div class="btn">
                <a class="personcenter fl" href="{% url 'users: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 %}

运行项目,从右上角的用户信息中可进入个人中心。

在后台管理系统中添加一个生日,便可以把信息都进行显示。

2.修改头像

进行头像图片的修改:

使用modelform来进行文件的上传

在apps/users/forms.py中:

# 省略
from apps.users.models import UserProfile

# 上传头像的表单
class UploadImageForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        # 只需要image字段
fields = ["image"]

# 注册的表单
# 省略

在apps/users/views.py中:

# 省略
from django.contrib.auth.mixins import LoginRequiredMixin

from apps.users.forms import LoginForm, DynamicLoginForm, DynamicLoginPostForm, UploadImageForm
from apps.users.forms import RegisterGetForm, RegisterPostForm
from apps.utils.YunPian import send_single_sms
from apps.utils.random_str import generate_random
from MxOnline.settings import yp_apikey, REDIS_HOST, REDIS_PORT
from apps.users.models import UserProfile


# Create your views here.

# 进行头像的修改
class UploadImageView(LoginRequiredMixin, View):
    login_url = "/login/"
# # 打开文件进行写入
# def save_file(self, file):
    #     with open("C:/Users/Administrator/PycharmProjects/MxOnline/media/head_image/uploaded.jpg", "wb") as f:
    #         for chunk in file.chunks():
    #             f.write(chunk)

def post(self, request, *args, **kwargs):
        # 处理用户上传的头像
# 使用此modelform来进行文件的上传,可解决文件上传多次、文件保存路径写入到user、表单验证的功能,instance=request.user指明修改的实例
image_form = UploadImageForm(request.POST, request.FILES, instance=request.user)
        # 进行表单的验证
if image_form.is_valid():
            image_form.save()
            return JsonResponse({
                "status": "success"
})
        else:
            return JsonResponse({
                "status": "fail"
})
        # files = request.FILES["image"]
        # self.save_file(files)


# 用户信息
# 省略

在apps/users/urls.py中:

from django.conf.urls import url

from apps.users.views import UserInfoView, UploadImageView



urlpatterns = [
    # 用户信息
url(r'^info/$', UserInfoView.as_view(), name="info"),
# 进行头像上传
url(r'^image/upload/$', UploadImageView.as_view(), name="image"),

]

在templates/usercenter-info.html中修改action(25行):

<form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="{% url 'users:image' %}" target='frameFile'>

34行加入csrf_token,否则会报403的错误:

    </label>
{% csrf_token %}
</form>

点击修改头像并上传,便可完成头像的修改。

3.修改用户信息

在templates/usercenter-info.html中加入csrf_token:

       <li class="button heibtn">
         <input type="button" id="jsEditUserBtn" value="保存">
      </li>
   </ul>
            {% csrf_token %}
</form>

在class UserInfoView中编写接口修改用户信息:

在apps/users/forms.py中:

# 省略
from apps.users.models import UserProfile

# 修改个人信息的表单
class UserInfoForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ["nick_name", "gender", "birthday", "address"]
        
# 上传头像的表单
# 省略

在apps/users/views.py中:

# 用户信息
class UserInfoView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        return render(request, "usercenter-info.html")

    def post(self, request, *args, **kwargs):
        user_info_form = UserInfoForm(request.POST, instance=request.user)
        if user_info_form.is_valid():
            user_info_form.save()
            return JsonResponse({
                "status": "success"
            })
        else:
            return JsonResponse(user_info_form.errors)

运行项目,修改信息后点击保存便完成信息的修改。

4.修改密码

在templates/usercenter-base.html中添加csrf_token(214行):

    <div class="button">
        <input id="jsResetPwdBtn" type="button" value="提交" />
    </div>
    {% csrf_token %}
</form>

在apps/users/forms.py中:

# 省略
# 修改密码的表单
class ChangePwdForm(forms.Form):
    password1 = forms.CharField(required=True, min_length=5)
    password2 = forms.CharField(required=True, min_length=5)

    def clean(self):
        pwd1 = self.cleaned_data["password1"]
        pwd2 = self.cleaned_data["password2"]

        if pwd1 != pwd2:
            raise forms.ValidationError("密码不一致")
        return self.cleaned_data

# 修改个人信息的表单
# 省略

在apps/users/views.py中:

# 省略
# Create your views here.


# 进行密码的修改
class ChangePwdView(LoginRequiredMixin, View):
    login_url = "/login/"
    def post(self, request, *args, **kwargs):
        pwd_form = ChangePwdForm(request.POST)
        if pwd_form.is_valid():
            # # 判断两次输入密码是否一致,或将表单的验证放到form中完成
            # pwd1 = request.POST.get("password1", "")
            # pwd2 = request.POST.get("password2", "")
            #
            # if pwd1 != pwd2:
            #     return JsonResponse({
            #         "status":"fail",
            #         "msg":"密码不一致"
            #     })
            pwd1 = request.POST.get("password1", "")
            user = request.user
            user.set_password(pwd1)
            user.save()
            # # Django中修改完密码会自动退出,若不自动退出,使用以下方法
            # login(request, user)

            return JsonResponse({
                "status":"success"
            })
        else:
            return JsonResponse(pwd_form.errors)

# 进行头像的修改
# 省略

在apps/users/urls.py中:

from django.conf.urls import url

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView



urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),

]

菜单栏-Edit-Find-Find in path

勾选html文件,搜索usercenter-info.html,-Open in Find Window

将代码中所有usercenter-info.html修改为{% url 'users:info' %}

运行项目,可进行密码的修改,在修改完成后会自动退到登录页面。

5.修改手机号码

将验证码进行显示

在apps/users/views.py中:

# 用户信息
class UserInfoView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        captcha_form = RegisterGetForm()
        return render(request, "usercenter-info.html", {
            "captcha_form": captcha_form,
        })
    # 省略

在templates/usercenter-base.html中:(226行)

<p>请输入新的手机号码</p>
<form id="jsChangePhoneForm" autocomplete="off">
    <div class="box">
        <input class="fl change_mobile" type="text" id="jsChangePhone" name="mobile" autocomplete="off" placeholder="输入重新绑定的手机号码">
    </div>
    <div class="box">
        {{ captcha_form.captcha }}
    </div>

刷新页面,点击手机号码的修改,便可显示验证码。

在apps/users/forms.py中:

# 省略
from apps.users.models import UserProfile


# 修改手机号码的表单
class UpdateMobileForm(forms.Form):
    mobile = forms.CharField(required=True, min_length=11, max_length=11)
    code = forms.CharField(required=True, min_length=4, max_length=4)

    # 看验证码是否在数据库中(之前是否发送过验证码)
    def clean_code(self):
        mobile = self.data.get("mobile")
        code = self.data.get("code")
        r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0, charset="utf8", decode_responses=True)
        redis_code = r.get(str(mobile))
        if code != redis_code:
            raise forms.ValidationError("验证码不正确")
        return self.cleaned_data


# 修改密码的表单
# 省略

在apps/users/views.py中:

# 省略
from apps.users.models import UserProfile


# Create your views here.

# 修改手机号码
class ChangeMobileView(LoginRequiredMixin, View):
    login_url = "/login/"
    def post(self, request, *args, **kwargs):
        mobile_form = UpdateMobileForm(request.POST)
        if mobile_form.is_valid():
            mobile = mobile_form.cleaned_data["mobile"]
            # 已经存在的记录不能重复注册
            # if request.user.mobile == mobile:
            #     return JsonResponse({
            #         "mobile": "和当前号码一致"
            #     })
            if UserProfile.objects.filter(mobile=mobile):
                return JsonResponse({
                    "mobile": "该手机号码已经被占用"
                })
            # 进行修改
            user = request.user
            user.mobile = mobile
            # 将用户名也进行修改,否则登录会出现问题
            user.username = mobile
            user.save()
            return JsonResponse({
                "status": "success"
            })
        else:
            return JsonResponse(mobile_form.errors)
            # # 若需要修改后退出登录
            # logout(request)

# 进行密码的修改
# 省略

在apps/users/urls.py中:

from django.conf.urls import url

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView, ChangeMobileView



urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),
    # 手机号码修改
    url(r'^update/mobile/$', ChangeMobileView.as_view(), name="update_mobile"),

]

在templates/usercenter-base.html中(234行):

    <div class="box">
        <input class="fl" type="text" id="jsChangePhoneCode" name="code" placeholder="输入手机验证码">
        <input class="getcode getting" type="button" id="jsChangePhoneCodeBtn" value="获取验证码">
    </div>
    <div class="error btns" id="jsChangePhoneTips" style="display: none;"></div>
    <div class="button">
        <input type="button" value="完成" id="jsChangePhoneBtn">
    </div>
{% csrf_token %}

运行项目,便可完成手机号码的修改。

6.我的课程页面

在apps/users/views.py中:

# 我的课程
class MyCourseView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        # 侧边栏选中状态的配置
        current_page = "mycourse"
        # my_courses = UserCourse.objects.filter(user=request.user)
        return render(request, "usercenter-mycourse.html", {
            # "my_courses": my_courses,
            "current_page": current_page
        })
# 省略
# 用户信息
class UserInfoView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        current_page = "info"
        captcha_form = RegisterGetForm()
        return render(request, "usercenter-info.html", {
            "captcha_form": captcha_form,
            "current_page": current_page
        })
    # 省略

在apps/users/urls.py中:

from django.conf.urls import url
from django.views.generic import TemplateView
from django.contrib.auth.decorators import login_required

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView, ChangeMobileView
from apps.users.views import MyCourseView


urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),
    # 手机号码修改
    url(r'^update/mobile/$', ChangeMobileView.as_view(), name="update_mobile"),
    # 我的课程
    url(r'^mycourse/$', MyCourseView.as_view(), name="mycourse"),
    # # 或者可以不写MyCourseView,直接使用TemplateView,使用login_required来进行登录的验证,并传入current_page参数
    # url(r'^mycourse/$',login_required(TemplateView.as_view(template_name="usercenter-mycourse.html"), login_url="/login/"),{"current_page": "mycourse"}, name="mycourse"),
]

在templates/usercenter-mycourse.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="{% url 'users:info' %}">个人中心</a>></li>
                <li>我的课程</li>
            </ul>
        </div>
    </section>
{% endblock %}

{% block right_form %}
        <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">
                <!-- 可反向取,不在views中取值 -->
                    {% for user_course in user.usercourse_set.all %}
                    <div class="module1_5 box">
                            <!-- user_course有一个外键course -->
                            <a href="{% url 'course:detail' user_course.course.id %}">
                                <img width="214" height="190" class="scrollLoading" src="{{ user_course.course.image.url }}"/>
                            </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">
                                <!-- course_org为course的外键 -->
                                <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 %}

在templates/usercenter-base.html中(93行):

            <li class="{% if current_page == 'info' %}active2{% endif %}"><a href="{% url 'users:info' %}">个人资料</a></li>
            <li class="{% if current_page == 'mycourse' %}active2{% endif %}"><a href="{% url 'users:mycourse' %}">我的课程</a></li>
            <li ><a href="usercenter-fav-course.html">我的收藏</a></li>

7.我的收藏

7.1 课程机构

在apps/users/views.py中:

# 省略
from apps.operations.models import UserFavorite
from apps.organizations.models import CourseOrg

# Create your views here.


# 我的收藏-课程机构
class MyFavOrgView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        current_page = "myfavorg"
        org_list = []
        # 获取机构信息
        fav_orgs = UserFavorite.objects.filter(user=request.user, fav_type=2)
        for fav_org in fav_orgs:
            org = CourseOrg.objects.get(id=fav_org.fav_id)
            org_list.append(org)
        return render(request, "usercenter-fav-org.html",{
            "org_list": org_list,
            "current_page": current_page
        })

# 我的课程
# 省略

在apps/users/urls.py中:

from django.conf.urls import url
from django.views.generic import TemplateView
from django.contrib.auth.decorators import login_required

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView, ChangeMobileView
from apps.users.views import MyCourseView, MyFavOrgView


urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),
    # 手机号码修改
    url(r'^update/mobile/$', ChangeMobileView.as_view(), name="update_mobile"),
    # 我的课程
    url(r'^mycourse/$', MyCourseView.as_view(), name="mycourse"),
    # # 或者可以不写MyCourseView,直接使用TemplateView,使用login_required来进行登录的验证,并传入current_page参数
    # url(r'^mycourse/$',login_required(TemplateView.as_view(template_name="usercenter-mycourse.html"), login_url="/login/"),{"current_page": "mycourse"}, name="mycourse"),
    # 我的收藏-课程机构
    url(r'^myfavorg/$', MyFavOrgView.as_view(), name="myfavorg"),
]

在templates/usercenter-fav-org.html中:

{% extends 'usercenter-base.html' %}
{% block title %}我的收藏- 慕学在线网{% endblock %}
{% load staticfiles %}
{% block custom_bread %}
     <section>
        <div class="wp">
            <ul  class="crumbs">
                <li><a href="{% url 'index' %}">首页</a>></li>
                <li><a href="{% url 'users:info' %}">个人中心</a>></li>
                <li>我的收藏</li>
            </ul>
        </div>
    </section>
{% endblock %}

{% block right_form %}
   <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="{% url 'users:myfavorg' %}">课程机构</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:home' org.id %}">
                                    <img width="160" height="90" src="{{ org.image.url }}"/>
                                </a>
                            </dt>
                            <dd>
                                <h1><a href="{% url 'org:home' org.id %}">{{ org.name }}</a></h1>
                                <div class="pic fl" style="width:auto;">
                                {% if org.is_auth %}
                                    <img src="{% static 'images/authentication.png' %}"/>
                                {% endif %}
                                {% if org.is_gold %}
                                    <img src="{% static 'images/gold.png' %}"/>
                                {% endif %}
                                </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 %}

{% block custom_js %}
<script type="text/javascript">
     $('.jsDeleteFav_org').on('click', function () {
            var _this = $(this),
                favid = _this.attr('data-favid');
            $.ajax({
                cache: false,
                type: "POST",
                url: "{% url 'op:fav' %}",
                data: {
                    fav_type: 2,
                    fav_id: favid,
                    csrfmiddlewaretoken: '{{ csrf_token }}'
                },
                async: true,
                success: function (data) {
                    Dml.fun.winReload();
                }
            });
        });
</script>
{% endblock %}

在templates/usercenter-base.html中:(93行左右)

<li class="{% if current_page == 'info' %}active2{% endif %}"><a href="{% url 'users:info' %}">个人资料</a></li>
<li class="{% if current_page == 'mycourse' %}active2{% endif %}"><a href="{% url 'users:mycourse' %}">我的课程</a></li>
<li class="{% if current_page == 'myfavorg' %}active2{% endif %}"><a href="{% url 'users:myfavorg' %}">我的收藏</a></li>

删除机构收藏按钮:

在templates/usercenter-base.html中可将此段代码注释掉(350行左右):

已写在了templates/usercenter-fav-org.html中。

{#$(document).ready(function() {#}
{#    $('.jsDeleteFav_org').on('click', function () {#}
{#        var _this = $(this),#}
{#            favid = _this.attr('data-favid');#}
{#        $.ajax({#}
{#            cache: false,#}
{#            type: "POST",#}
{#            url: "{% url 'op:fav' %}",#}
{#            data: {#}
{#                fav_type: 2,#}
{#                fav_id: favid,#}
{#                csrfmiddlewaretoken: '{{ csrf_token }}'#}
{#            },#}
{#            async: true,#}
{#            success: function (data) {#}
{#                Dml.fun.winReload();#}
{#            }#}
{#        });#}
{#    });#}
{# });#}

便可进行我的收藏中课程展示,以及课程机构的删除。

7.2 授课讲师

在templates/usercenter-fav-teacher.html中:

{% extends 'usercenter-base.html' %}
{% block title %}我的收藏- 慕学在线网{% endblock %}
{% load staticfiles %}
{% block custom_bread %}
     <section>
        <div class="wp">
            <ul  class="crumbs">
                <li><a href="{% url 'index' %}">首页</a>></li>
                <li><a href="{% url 'users:info' %}">个人中心</a>></li>
                <li>我的收藏</li>
            </ul>
        </div>
    </section>
{% endblock %}

{% block right_form %}
    <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:myfavorg' %}">课程机构</a> </li>
                        <li class="active"><a href="{% url 'users:myfav_teachers' %}">授课教师 </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="{{ teacher.image.url }}"/>
                                </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.course_set.all.count }}</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 %}

{% block custom_js %}
<script type="text/javascript">
    $('.jsDeleteFav_teacher').on('click', function () {
            var _this = $(this),
                favid = _this.attr('data-favid');
            $.ajax({
                cache: false,
                type: "POST",
                url: "{% url 'op:fav' %}",
                data: {
                    fav_type: 3,
                    fav_id: favid,
                    csrfmiddlewaretoken: '{{ csrf_token }}'
                },
                async: true,
                success: function (data) {
                    Dml.fun.winReload();
                }
            });
        });
</script>
{% endblock %}

在apps/users/views.py中:

# 省略
from apps.organizations.models import CourseOrg, Teacher


# Create your views here.

# 我的收藏-授课教师
class MyFavTeacherView(LoginRequiredMixin, View):
    login_url = "/login/"

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


# 我的收藏-课程机构
# 省略

在apps/users/urls.py中:

from django.conf.urls import url
from django.views.generic import TemplateView
from django.contrib.auth.decorators import login_required

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView, ChangeMobileView
from apps.users.views import MyCourseView, MyFavOrgView, MyFavTeacherView


urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),
    # 手机号码修改
    url(r'^update/mobile/$', ChangeMobileView.as_view(), name="update_mobile"),
    # 我的课程
    url(r'^mycourse/$', MyCourseView.as_view(), name="mycourse"),
    # # 或者可以不写MyCourseView,直接使用TemplateView,使用login_required来进行登录的验证,并传入current_page参数
    # url(r'^mycourse/$',login_required(TemplateView.as_view(template_name="usercenter-mycourse.html"), login_url="/login/"),{"current_page": "mycourse"}, name="mycourse"),
    # 我的收藏-课程机构
    url(r'^myfavorg/$', MyFavOrgView.as_view(), name="myfavorg"),
    # 我的收藏-授课教师
    url(r'^myfav_teacher/$', MyFavTeacherView.as_view(), name="myfav_teachers"),
]

在templates/usercenter-fav-org.html中(27行左右):

<li class="active"><a href="{% url 'users:myfavorg' %}">课程机构</a> </li>
<li><a href="{% url 'users:myfav_teachers' %}">授课教师 </a></li>
<li><a href="usercenter-fav-course.html">公开课程</a></li>

运行项目,便可进行我的收藏中授课教师的浏览和删除。

7.3 公开课程

在apps/users/views.py中:

# 省略
from apps.organizations.models import CourseOrg, Teacher
from apps.courses.models import Course


# Create your views here.

# 我的收藏-公开课程
class MyFavCourseView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        current_page = "myfav_course"
        course_list = []
        fav_courses = UserFavorite.objects.filter(user=request.user, fav_type=1)
        for fav_course in fav_courses:
            # 若课程id不存在,做异常处理
            try:
                course = Course.objects.get(id=fav_course.fav_id)
                course_list.append(course)
            except Course.DoesNotExist as e:
                pass
        return render(request, "usercenter-fav-course.html",{
            "course_list": course_list,
            "current_page": current_page
        })

# 我的收藏-授课教师
# 省略

在apps/users/urls.py中:

from django.conf.urls import url
from django.views.generic import TemplateView
from django.contrib.auth.decorators import login_required

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView, ChangeMobileView
from apps.users.views import MyCourseView, MyFavOrgView, MyFavTeacherView, MyFavCourseView


urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),
    # 手机号码修改
    url(r'^update/mobile/$', ChangeMobileView.as_view(), name="update_mobile"),
    # 我的课程
    url(r'^mycourse/$', MyCourseView.as_view(), name="mycourse"),
    # # 或者可以不写MyCourseView,直接使用TemplateView,使用login_required来进行登录的验证,并传入current_page参数
    # url(r'^mycourse/$',login_required(TemplateView.as_view(template_name="usercenter-mycourse.html"), login_url="/login/"),{"current_page": "mycourse"}, name="mycourse"),
    # 我的收藏-课程机构
    url(r'^myfavorg/$', MyFavOrgView.as_view(), name="myfavorg"),
    # 我的收藏-授课教师
    url(r'^myfav_teacher/$', MyFavTeacherView.as_view(), name="myfav_teachers"),
    # 我的收藏-公开课程
    url(r'^myfav_course/$', MyFavCourseView.as_view(), name="myfav_course"),
]

在templates/usercenter-fav-course.html中:

{% extends 'usercenter-base.html' %}
{% block title %}我的收藏- 慕学在线网{% endblock %}
{% load staticfiles %}
{% block custom_bread %}
     <section>
        <div class="wp">
            <ul  class="crumbs">
                <li><a href="{% url 'index' %}">首页</a>></li>
                <li><a href="{% url 'users:info' %}">个人中心</a>></li>
                <li>我的收藏</li>
            </ul>
        </div>
    </section>
{% endblock %}

{% block right_form %}
        <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:myfavorg' %}">课程机构</a> </li>
                        <li><a href="{% url 'users:myfav_teachers' %}">授课教师 </a></li>
                        <li class="active"><a href="{% url 'users:myfav_course' %}">公开课程</a></li>
                    </ul>

                </div>
                <div class="companycenter">
                    <div class="group_list brief">
                        {% for course in course_list %}
                        <div class="module1_5 box">
                            <a href="{% url 'course:detail' course.id %}">
                                <img width="214" height="190" src="{{ course.image.url }}"/>
                            </a>
                            <div class="des">
                                <a href="{% url 'course:detail' course.id %}"><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="delete-group fr jsDeleteFav_course" data-favid="{{ course.id }}"></span>
                            </div>
                        </div>
                        {% endfor %}
                    </div>
                </div>
            </div>
        </div>

{% endblock %}

{% block custom_js %}
<script type="text/javascript">
    $('.jsDeleteFav_course').on('click', function () {
            var _this = $(this),
                favid = _this.attr('data-favid');
            $.ajax({
                cache: false,
                type: "POST",
                url: "{% url 'op:fav' %}",
                data: {
                    fav_type: 1,
                    fav_id: favid,
                    csrfmiddlewaretoken: '{{ csrf_token }}'
                },
                async: true,
                success: function (data) {
                    Dml.fun.winReload();
                }
            });
        });
</script>
{% endblock %}

可将templates/usercenter-base.html中关于删除收藏的script的代码都删除:

<script type="text/javascript">标签内的都删除

<script type="text/javascript">
    $(document).ready(function() {
    # 省略
</script>

在templates/usercenter-fav-org.html中:(29行)

<li><a href="{% url 'users:myfav_course' %}">公开课程</a></li>

在templates/usercenter-fav-teacher.html中:(28行)

<li><a href="{% url 'users:myfav_course' %}">公开课程</a></li>

运行项目,便可进行我的收藏中公开课程的浏览和删除。

再配置一下选中的状态:

在templates/usercenter-base.html中:

<li class="{% if current_page == 'info' %}active2{% endif %}"><a href="{% url 'users:info' %}">个人资料</a></li>
<li class="{% if current_page == 'mycourse' %}active2{% endif %}"><a href="{% url 'users:mycourse' %}">我的课程</a></li>
<li class="{% if current_page == 'myfavorg' or current_page == 'myfav_teacher' or current_page == 'myfav_course' %}active2{% endif %}"><a href="{% url 'users:myfavorg' %}">我的收藏</a></li>

8.我的消息

在apps/users/views.py中:

# 省略
from apps.courses.models import Course


# Create your views here.

# 我的消息
class MyMessageView(LoginRequiredMixin, View):
    login_url = "/login/"

    def get(self, request, *args, **kwargs):
        messages = UserMessage.objects.filter(user=request.user)
        current_page = "message"
        for message in messages:
            message.has_read = True
            message.save()

        # 对消息进行分页
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1

        p = Paginator(messages, per_page=1, request=request)
        messages = p.page(page)

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

# 我的收藏-公开课程
# 省略

在apps/users/urls.py中:

from django.conf.urls import url
from django.views.generic import TemplateView
from django.contrib.auth.decorators import login_required

from apps.users.views import UserInfoView, UploadImageView, ChangePwdView, ChangeMobileView
from apps.users.views import MyCourseView, MyFavOrgView, MyFavTeacherView, MyFavCourseView, MyMessageView


urlpatterns = [
    # 用户信息
    url(r'^info/$', UserInfoView.as_view(), name="info"),
    # 进行头像上传
    url(r'^image/upload/$', UploadImageView.as_view(), name="image"),
    # 密码修改
    url(r'^update/pwd/$', ChangePwdView.as_view(), name="update_pwd"),
    # 手机号码修改
    url(r'^update/mobile/$', ChangeMobileView.as_view(), name="update_mobile"),
    # 我的课程
    url(r'^mycourse/$', MyCourseView.as_view(), name="mycourse"),

    # # 或者可以不写MyCourseView,直接使用TemplateView,使用login_required来进行登录的验证,并传入current_page参数
    # url(r'^mycourse/$',login_required(TemplateView.as_view(template_name="usercenter-mycourse.html"), login_url="/login/"),{"current_page": "mycourse"}, name="mycourse"),

    # 我的收藏-课程机构
    url(r'^myfavorg/$', MyFavOrgView.as_view(), name="myfavorg"),
    # 我的收藏-授课教师
    url(r'^myfav_teacher/$', MyFavTeacherView.as_view(), name="myfav_teachers"),
    # 我的收藏-公开课程
    url(r'^myfav_course/$', MyFavCourseView.as_view(), name="myfav_course"),
    # 我的消息
    url(r'^messages/$', MyMessageView.as_view(), name="messages"),

]

在templates/usercenter-message.html中:

{% extends 'usercenter-base.html' %}
{% block title %}我的消息- 慕学在线网{% endblock %}
{% load staticfiles %}
{% block custom_bread %}
     <section>
        <div class="wp">
            <ul  class="crumbs">
                <li><a href="{% url 'index' %}">首页</a>></li>
                <li><a href="{% url 'users:info' %}">个人中心</a>></li>
                <li>我的消息</li>
            </ul>
        </div>
    </section>
{% endblock %}

{% block right_form %}
    <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="{% url 'users:messages' %}">个人消息</a> </li>
            </ul>


         </div>
         <div class="messagelist">

                    <div class="messages">
                        {% for message in messages.object_list %}
                        <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>
                        {% endfor %}
                    </div>



         </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">...</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 %}

在templates/usercenter-base.html中:(93行)

<li class="{% if current_page == 'info' %}active2{% endif %}"><a href="{% url 'users:info' %}">个人资料</a></li>
<li class="{% if current_page == 'mycourse' %}active2{% endif %}"><a href="{% url 'users:mycourse' %}">我的课程</a></li>
<li class="{% if current_page == 'myfavorg' or current_page == 'myfav_teacher' or current_page == 'myfav_course' %}active2{% endif %}"><a href="{% url 'users:myfavorg' %}">我的收藏</a></li>
<li class="{% if current_page == 'message' %}active2{% endif %}">
    <a href="{% url 'users:messages' %}" style="position: relative;">
        我的消息
    </a>
</li>

右上角未读消息的显示:

在apps/users/models.py中:

    # 省略
    image = models.ImageField(verbose_name="用户头像", upload_to="head_image/%Y/%m", default="default.jpg")

    class Meta:
        verbose_name = "用户信息"
        verbose_name_plural = verbose_name

    def unread_nums(self):
        # 未读消息数量
        return self.usermessage_set.filter(has_read=False).count()

    # 得到UserProfile时,字符串的描述,直接输出时用
    # 省略

注入全局的html变量:

在apps/users/views.py中:

# 省略
from apps.courses.models import Course


# Create your views here.

# 未读消息,注入全局的html变量
def message_nums(request):
    """
    Add media-related context variables to the context.
    """
    if request.user.is_authenticated:
        return {'unread_nums': request.user.usermessage_set.filter(has_read=False).count()}
    else:
        return {}

# 我的消息
# 省略

在MxOnline/settings.py中:

# 省略
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            # 上下文机制
            'context_processors': [
                'django.template.context_processors.debug',
                # request为全局变量,这些值会默认放到所有的html页面中
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                # 配置全局media的url,可点入源码查看
                'django.template.context_processors.media',
                # 配置全局的未读消息变量message_nums
                'apps.users.views.message_nums'
            ],
        },
    },
]
# 省略

在templates/usercenter-base.html中(53行):

    <!--如果用户未登录-->
    <a style="color:white" class="fr registerbtn" href="{% url 'register' %}">注册</a>
    <a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登录</a>
{% endif %}
<a href="{% url 'users:messages' %}">
    <div class="msg-num"><span id="MsgNum">{{ unread_nums }}</span></div>
</a>

在templates/base.html中(50行):

    <!--如果用户未登录-->
    <a style="color:white" class="fr registerbtn" href="{% url 'register' %}">注册</a>
    <a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登录</a>
{% endif %}
<a href="{% url 'users:messages' %}">
    <div class="msg-num"><span id="MsgNum">{{ unread_nums }}</span></div>
</a>

在templates/index.html(90行):

<a href="{% url 'org:teachers' %}">授课教师</a>

在templates/org_base.html中(51行):

    <!--如果用户未登录-->
    <a style="color:white" class="fr registerbtn" href="{% url 'register' %}">注册</a>
    <a style="color:white" class="fr loginbtn" href="{% url 'login' %}">登录</a>
{% endif %}
<a href="{% url 'users:messages' %}">
    <div class="msg-num"><span id="MsgNum">{{ unread_nums }}</span></div>
</a>

运行项目,若有未读消息变会在上方显示数量,在点击我的消息页面后,未读消息数量清零。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值