1. 程式人生 > >Django網站建設-頭像修改,郵箱及密碼修改(form,js檔案,模板配置)

Django網站建設-頭像修改,郵箱及密碼修改(form,js檔案,模板配置)

1.選擇好模板,並分析頁面
2.修改並自定義基礎模板
3.修改各個頁面,修改title,麵包屑等
4.定義好使用者資訊的View
5. 資料繫結,資料回填
6. 配置路徑利用include
7. 模板顯示,在模板中顯示預設值:{{request.user.mobile|default_if_none:”}}

個人中心頁面配置 (注意debug的使用方法)

製作個人中心基礎模板(usercenter_base),配置基礎快

{% load staticfiles %}
{% block custom_css %}{% endblock %}
{% block header %}{% endblock %}
{% block bread %}{% endblock %}
{% block content_left %}{% endblock %}
{% block content_right %}{% endblock %}
{% block header %}{% endblock %}
{% block custom_js %}{% endblock %}

在基礎模板中完成能複用的程式碼塊的資料繫結及配置(block-header)

{% block header %}
<section class="headerwrap headerwrap2">
    <header>
        <div  class="header2 header">
            {% if request.user.is_authenticated %}
                <div class="top">
                <div class="wp">
                    <div class="fl">
                        <p>服務電話:<b>33333333</b></p>
                    </div>
                        <!--登入後跳轉-->

                        <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 }}{{ user.img }}"/></dt>
                            </dl>
                            <div class="userdetail">
                                <dl>
                                    <dt><img width="80" height="80" src="{{ MEDIA_URL }}{{ user.img }}"/></dt>
                                    <dd>
                                        <h2>{{ user.gender }}</h2>
                                        <p>{{ user.username }}</p>
                                    </dd>
                                </dl>
                                <div class="btn">
                                    <a class="personcenter fl" href="usercenter_info.html">進入個人中心</a>
                                    <a class="fr" href="{% url 'user_loginout' %}?next={{ request.path }}">退出</a>
                                    <a href="usercenter-message.html">
                                    <div class="msg-num"><span id="MsgNum">0</span></div>
                                    </a>
                                </div>
                            </div>
                        </div>
                    </div>
            </div>
                {% else %}
                <div class="top">
                        <div class="wp">
                            <div class="fl">
                                <p>服務電話:<b>33333333</b></p></div>
                            <a style="color:white" class="fr registerbtn" href="{% url 'Register' %}">註冊</a>
                            <a style="color:white" class="fr loginbtn" href="{% url 'user_login' %}?next={{ request.path }}">登入</a>
                        </div>
                    </div>
            {% endif %}
    <div class="middle">
        <div class="wp">
            <a href="index.html"><img class="fl" src="{% static 'images/logo2.png' %}"/></a>
            <h1>我的慕學網</h1>
        </div>
    </div>
            </div>
    </header>
</section>
{% endblock %}

對使用者中的模板進行資料繫結,主要是custom_right程式碼塊

{% block content_right %}
        <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_URL }}{{ user.img }}">
                            </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' />
                    </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>暱&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;稱:
                           <input type="text" name="nick_name" id="nick_name" value="{{ user.nick_name }}" maxlength="10">
                            <i class="error-tips"></i>
                        </li>
                        <li>生&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;日:
                           <input type="text" id="birth_day" name="birday" value="{{ user.birthday }}" readonly="readonly"/>
                            <i class="error-tips"></i>
                        </li>
                        <li>性&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;別:
                            <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio"  name="gender" value="male" {% if user.gender == 'male' %}checked="checked"{% endif %} >男</label>
                            <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" name="gender" value="female" {% if user.gender == 'female' %}checked="checked"{% endif %}>女</label>
                        </li>
                        <li class="p_infor_city">地&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;址:
                            <input type="text" name="address" id="address" placeholder="請輸入你的地址" value="{{ user.adress }}" maxlength="10">
                            <i class="error-tips"></i>
                        </li>
                        <li>手&nbsp;&nbsp;機&nbsp;&nbsp;號:
                            <input type="text" name="mobile" id="mobile" placeholder="請輸入你的手機號碼" value="{{ user.mobile }}" maxlength="10">
                        </li>
                        <li>郵&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱:
                            <input class="borderno" type="text" name="email" readonly="readonly" value="{{ user.email }}"/>
                            <span class="green changeemai_btn">[修改]</span>
                        </li>
                        <li class="button heibtn">
                            <input type="button" id="jsEditUserBtn" value="儲存">
                        </li>
                    </ul>
                    <input type='hidden' name='csrfmiddlewaretoken' value='799Y6iPeEDNSGvrTu3noBrO4MBLv6enY' />
                </form>
            </div>
        </div>
    </div>
{% endblock %}

配置url分發路徑

url(r'^user_center/', include('users.url', namespace='user_info')),# organiztion 的url分發,namespace用於重名的處理

配置實際url路徑

urlpatterns = [
url(r’^user_info/$’, UserInfoView.as_view(), name=’user_info’),
]

配置檢視函式,在後臺進行登陸驗證,未完成登陸則首先獲取來時路徑(request.path),再構造完成login的路徑(繫結來時路徑next_page,格式與前面login函式對應),最後重定向至login頁面,如果已經登陸則渲染正確頁面進行展示

class UserInfoView(View):
    def get(self,request):
        next_page = request.path   #獲取來時路徑
        #判斷是否登陸
        if not request.user.is_authenticated():
            #return render(request,'usercenter_info.html',{})
            target_url = '/login/?next='+next_page      #拼湊成與login對應的url
            return HttpResponseRedirect(target_url)  # 轉到來時頁面
        if request.user.is_authenticated():
            return render(request,'usercenter_info.html',{})

修改個人頭像

1.上傳檔案和圖片 ,需要定製一個url,並配置相應的後臺處理檢視函式view對其進行接收處理
2.通用檢視(登陸、許可權等)的繼承 10-1
3.定製modelform,進行表單提交
4.檢視函式中例項化form
5.檔案上傳會放在了request.FILES
6.前端利用form進行檔案的上傳,form表單的提交都需要加上csrf-token,檢視函式利用model_form進行資料轉換
7.image_form.clean_data[‘image’]獲取上傳檔案資訊,注意欄位與前端上傳的name保持一致
8.通過request.user.image=image進行修改資訊
9.利用save()進行儲存
10.利用HttpResponse進行資訊的反饋,提示使用者是否成功

配置url路徑

url(r'^user_img_upload/$', UserImgUploadView.as_view(), name='user_img_upload'),

修改模板,將form的上傳路徑(action)修改為上傳圖片地址路徑

               <form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="{% url 'user_info:user_img_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 }}{{ user.img }}">
                        </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>

建立圖片上傳表單form

class UserImgUploadForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['img']

建立圖片上傳的檢視邏輯,切記上傳圖片用的是post方法,對上傳的方法進行身份認證。檔案上傳都是放在request.FILES,所以需要將request.FILES傳入表單中,如果取值正確,則將form中的cleaned_data或files中會有檔案資訊,將檔案資訊儲存進request.user中,完成圖片更新

class UserImgUploadView(View):
    def post(self,request): #上傳是用post方法
        next_page = request.path   #獲取來時路徑
        #判斷是否登陸
        if not request.user.is_authenticated():
            target_url = '/login/?next='+next_page      #拼湊成與login對應的url
            return HttpResponseRedirect(target_url)  # 轉到來時頁面
        if request.user.is_authenticated():
            #可以進行圖片上傳工作
            img_upload_form = UserImgUploadForm(request.POST,request.FILES)
            if img_upload_form.is_valid():
                #驗證通過後會將上傳圖片放在cleaned_data內
                #image = img_upload_form.cleaned_data['img']
                image = img_upload_form.files['image']      #嘗試直接從files裡面取值
                #對獲取的圖片進行儲存
                request.user.img = image
                request.user.save()

修改密碼

1.邏輯類似user檢視中的修改密碼
2.利用ajax請求非同步修改密碼
3.後臺進行邏輯處理,並利用HttpResponse返回修改資訊
4.利用HttpResponse返回json資料,返回錯誤資訊 .errors
5.js檔案中需要寫入絕對路徑
6., content_type=’application/json’,這個引數別忘了

配置url不要重名,否者不會報錯,但是卻一直錯誤

Ajax的請求只能返回json

配置修改密碼post路徑

#使用者密碼修改
url(r'^password_update/$', UserPasswordUpdateView.as_view(), name='password_update'),

設定檢視函式,完成密碼驗證邏輯.現將密碼上傳至表單,注意name的一致性,判斷表單的正確性,獲取兩個密碼,判斷是否相同,邏輯正確的話進行密碼加密(make_password)儲存,邏輯錯誤的話返回錯誤資訊

表單驗證

is_valid()合法後的邏輯處理,驗證後的資料儲存在例項化後返回的cleaned_data中,cleaned_data是個字典的資料格式,錯誤資訊儲存在form.errors中比如說想在views中檢視所有報錯資訊print(f.errors)

class UserPasswordUpdateView(View):
    def post(self,request):
        password_reset_form = PasswordResetForm(request.POST)    #新密碼上傳至表單中
        if password_reset_form.is_valid():   #新設定的密碼符合表單的話
            password = request.POST.get('password','')
            password2 = request.POST.get('password2','')
            if password == password2: #兩個密碼相同,所有邏輯正確,進行密碼修改
                #在資料庫中資訊密碼修改
                request.user.password = make_password(password)
                request.user.save()
                return HttpResponse(json.dumps({'status': 'success'}),content_type='application/json')
            else:   #如果兩個密碼不相同
                return HttpResponse(json.dumps({'status': 'fail','msg':'密碼有誤'}), content_type='application/json')  # 將register_form資料傳遞給Template
        else:   #表單驗證不通過
            return HttpResponse(json.dumps({'status': 'fail', 'msg': password_reset_form.errors}),content_type='application/json')  # 將register_form資料傳遞給Template

郵箱修改

1.配置驗證碼傳送url,用於傳送郵箱驗資訊及驗證碼的上傳,注意Ajax裡面用的是get還是post方法
2.配置檢視函式,首先先進行登陸判斷,是否是已註冊郵箱的判斷
3.呼叫以前郵箱傳送功能,配置傳送email和send_type
4.登陸郵箱獲取驗證碼,填寫完整資訊,利用post進行傳送
5.檢視model是否定義錯誤

接收驗證碼

配置修改郵箱驗證碼傳送地址

 #接收郵箱驗證碼
    url(r'^send_email_code/$', EmailCodeView.as_view(), name='send_email_code'),

配置傳送驗證碼邏輯,先對身份進行驗證,然後對已有使用者是否存在相同郵箱進行驗證,成功則儲存郵箱驗證碼資訊,並返回Ajax資訊(注意get的資訊要與html檔案中的name一致)

#傳送更新郵箱驗證碼
class EmailCodeView(View):
    def get(self,request):
        #判斷是否登陸,如果未登陸則回到login頁面
        if not request.user.is_authenticated():
            return HttpResponseRedirect('/login/')  # 轉到來時頁面
        else:
            email = request.GET.get('email','')
            # 查詢該郵箱是否已經存在,如果有人已經用了該郵箱則不可以繼續用
            whether_exit_email = UserProfile.objects.filter(email=email)
            if whether_exit_email:
                #告訴使用者該郵箱已經存在
                return HttpResponse(json.dumps({'email': '郵箱已經存在'}), content_type='application/json')  # 將register_form資料傳遞給Template
            else:
                #郵箱不存在為可用郵箱,則傳送郵箱驗證碼,並在EmailVerifyCode進行儲存資料
                send_email(email, send_type='update')   #傳送驗證碼
                return HttpResponse(json.dumps({'status': 'success'}), content_type='application/json')  # 將register_form資料傳遞給Template

修改js資料夾下的js檔案,在該路徑下的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",    //注意這裡是用的get方法啦
        dataType:'json',
        url:"/user_center/send_email_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");
        }
    });
}

修改郵箱

配置更新郵箱的資訊接收url

#修改個人中心郵箱
url(r'^update_email/$', UpdateEmailView.as_view(), name='update_email'),

完成相應後臺邏輯,注意HttpResponse返回的josn資訊不要落下content_type=’application/json’,對身份進行驗證,利用郵箱及驗證碼聯合查詢驗證碼資料庫,進行驗證,成功則進行郵箱修改操作,並返回HttpResponse資訊

#郵箱更新view
class UpdateEmailView(View):
    def post(self,request):
        # 判斷是否登陸,如果未登陸則回到login頁面
        if not request.user.is_authenticated():
            return HttpResponseRedirect('/login/')  # 轉到來時頁面
        email = request.POST.get('email', '')
        code = request.POST.get('code', '')
        # 查詢該郵箱及驗證碼資訊
        exit_email = EmailVerifyCode.objects.filter(email=email,code=code)
        if exit_email:  #有該條記錄則驗證正確可以進行修改,完成驗證碼驗證功能,可以進行郵箱修改
            request.user.email = email
            request.user.save()
            return HttpResponse(json.dumps({'status': 'success'}), content_type='application/json')
        else:
            return HttpResponse(json.dumps({'status': 'fail'}), content_type='application/json')

個人資訊修改

配置url

url(r'^user_info/$', UserInfoView.as_view(), name='user_info'),

後臺邏輯

class UserInfoView(View):
    def get(self,request):
        next_page = request.path   #獲取來時路徑
        #判斷是否登陸
        if not request.user.is_authenticated():
            #return render(request,'usercenter_info.html',{})
            target_url = '/login/?next='+next_page      #拼湊成與login對應的url
            return HttpResponseRedirect(target_url)  # 轉到來時頁面
        if request.user.is_authenticated():
            return render(request,'usercenter_info.html',{})
    def post(self,request): #注意form表單需要加入csrf-tpken
        user_info_form = UserInfodForm(request.POST)
        if user_info_form.is_valid():
            request.user.nick_name = request.POST.get('nick_name')
            request.user.birthday = request.POST.get('birthday')
            request.user.gender = request.POST.get('gender')
            request.user.adress = request.POST.get('adress')
            request.user.mobile = request.POST.get('mobile')
            request.user.save()
            return HttpResponse(json.dumps({'status': 'success'}),content_type='application/json')  # 將register_form資料傳遞給Template
        else:
            return HttpResponse(json.dumps({'status': 'failure','msg':user_info_form.errors}),content_type='application/json')  # 將register_form資料傳遞給Template

html模板form表單完成資料繫結,切記form表單需要csrf-token

<form class="perinform" id="jsEditUserForm" autocomplete="off">
                    <ul class="right">
                        <li>暱&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;稱:
                           <input type="text" name="nick_name" id="nick_name" value="{{ user.nick_name }}" maxlength="10">
                            <i class="error-tips"></i>
                        </li>
                        <li>生&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;日:
                           <input type="text" id="birth_day" name="birthday" value="{{ user.birthday }}" readonly="readonly"/>
                            <i class="error-tips"></i>
                        </li>
                        <li>性&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;別:
                            <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio"  name="gender" value="male" {% if user.gender == 'male' %}checked="checked"{% endif %} >男</label>
                            <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" name="gender" value="female" {% if user.gender == 'female' %}checked="checked"{% endif %}>女</label>
                        </li>
                        <li class="p_infor_city">地&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;址:
                            <input type="text" name="adress" id="address" placeholder="請輸入你的地址" value="{{ user.adress }}" maxlength="10">
                            <i class="error-tips"></i>
                        </li>
                        <li>手&nbsp;&nbsp;機&nbsp;&nbsp;號:
                            <input type="text" name="mobile" id="mobile" placeholder="請輸入你的手機號碼" value="{{ user.mobile }}" maxlength="10">
                        </li>
                        <li>郵&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱:
                            <input class="borderno" type="text" name="email" readonly="readonly" value="{{ user.email }}"/>
                            <span class="green changeemai_btn">[修改]</span>
                        </li>
                        <li class="button heibtn">
                            <input type="button" id="jsEditUserBtn" value="儲存">
                        </li>
                    </ul>
                    <input type='hidden' name='csrfmiddlewaretoken' value='799Y6iPeEDNSGvrTu3noBrO4MBLv6enY' />
                {% csrf_token %}
                </form>

js檔案完成url地址配置(死地址,以後需要自己修改)

//儲存個人資料
    $('#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:"/user_center/user_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");
            }
        });
    });