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>暱 稱: <input type="text" name="nick_name" id="nick_name" value="{{ user.nick_name }}" maxlength="10"> <i class="error-tips"></i> </li> <li>生 日: <input type="text" id="birth_day" name="birday" value="{{ user.birthday }}" 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.adress }}" maxlength="10"> <i class="error-tips"></i> </li> <li>手 機 號: <input type="text" name="mobile" id="mobile" placeholder="請輸入你的手機號碼" value="{{ user.mobile }}" maxlength="10"> </li> <li>郵 箱: <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>暱 稱:
<input type="text" name="nick_name" id="nick_name" value="{{ user.nick_name }}" maxlength="10">
<i class="error-tips"></i>
</li>
<li>生 日:
<input type="text" id="birth_day" name="birthday" value="{{ user.birthday }}" 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="adress" id="address" placeholder="請輸入你的地址" value="{{ user.adress }}" maxlength="10">
<i class="error-tips"></i>
</li>
<li>手 機 號:
<input type="text" name="mobile" id="mobile" placeholder="請輸入你的手機號碼" value="{{ user.mobile }}" maxlength="10">
</li>
<li>郵 箱:
<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");
}
});
});