1. 程式人生 > >blog項目知識點梳理

blog項目知識點梳理

clas mouse ret image draw bytes 菜單 驗證碼 port

1.獲取圖片驗證碼:
def get_validCode_img(request):



    # 方式1:
    # import os
    # path= os.path.join(settings.BASE_DIR,"blog","static","img","egon.jpg")
    #
    # with open(path,"rb") as f:
    #     data=f.read()

    # 方式2:
    # from  PIL import Image
    #
    # img=Image.new(mode="RGB",size=(120,40),color="green")
# # f=open("validCode.png","wb") # img.save(f,"png") # # with open("validCode.png","rb") as f: # data=f.read() # 方式3: # from io import BytesIO # # from PIL import Image # img = Image.new(mode="RGB", size=(120, 40), color="blue") # f=BytesIO() #
img.save(f,"png") # data=f.getvalue() # return HttpResponse(data) # 方式4 : from io import BytesIO import random from PIL import Image,ImageDraw,ImageFont img = Image.new(mode="RGB", size=(120, 40), color=(random.randint(0,255),random.randint(0,255),random.randint(0,255))) draw
=ImageDraw.Draw(img,"RGB") font=ImageFont.truetype("blog/static/font/kumo.ttf",25) valid_list=[] for i in range(5): random_num=str(random.randint(0,9)) random_lower_zimu=chr(random.randint(65,90)) random_upper_zimu=chr(random.randint(97,122)) random_char=random.choice([random_num,random_lower_zimu,random_upper_zimu]) draw.text([5+i*24,10],random_char,(random.randint(0,255),random.randint(0,255),random.randint(0,255)),font=font) valid_list.append(random_char) f=BytesIO() img.save(f,"png") data=f.getvalue() valid_str="".join(valid_list) # print(valid_str) request.session["keepValidCode"]=valid_str return HttpResponse(data) 2.點擊驗證碼圖片刷新效果 $(.validCode_img).click(function () { console.log(this) this.src+="?" }) 3.註冊form組件註意事項 if form.is_valid(): username=form.cleaned_data[username] #如果form過濾驗證成功了 就直接在form.cleaned_data內取值就行,不必從request.POST中取值 password=form.cleaned_data[password] email=form.cleaned_data[email] tel=form.cleaned_data[tel] avatar = request.FILES.get("avatar") if not avatar: #用戶註冊時未選取頭像,那麽在創建新用戶時不用創建頭像字段,因為在models中已經設置了默認值,不然在數據庫中存的會是空 models.UserInfo.objects.create_user(username=username,password=password,email=email,telephone=tel) else: models.UserInfo.objects.create_user(username=username,password=password,email=email,telephone=tel,avatar=avatar) form組件的局部鉤子返回值 : return self.cleaned_data[xxx] 全局猴子返回值 : return self.cleaned_data #鉤子函數中在 clean_data 取值時, 要用 get方法 4.頭像預覽 <div class="form-group" id="i2"> {# 註意下面img與input 標簽的前後順序,如顛倒會出現點擊圖片不出現選擇圖片窗口 #} <label for="avatar">頭像</label> <img src="/static/img/default.png/" alt="" class="c1" id="i1"> <input type="file" id="avatar" class="c1"> </div> $("#avatar").change(function () { var ele_file=$(this)[0].files[0]; //$(this)[0]和this 一樣 var reader=new FileReader(); reader.readAsDataURL(ele_file); reader.onload=function () { $("#i1")[0].src=this.result } }); 5.註冊時返回的錯誤信息的處理 var errors_msg=data1[errors_msg]; $.each(errors_msg,function (i,v) { {# console.log(i,v);#} var ele=$(<span>); ele.html(v[0]).addClass(pull-right).css(color,red); $(#+i).after(ele).parent().addClass(has-error) if(i==__all__){ $(#repassword).after(ele).parent().addClass(has-error) } }) 6.ajax在提交二進制數據時用formData var formData=new FormData(); formData.append(username,$(#username).val()); formData.append(avatar,$(#avatar)[0].files[0]); $.ajax({ url:/reg/, type:POST, data:formData, contentType:false, processData:false, headers:{"X-CSRFToken":$.cookie(csrftoken)}, #需要引用 <script src="/static/js/jquery.cookie.js"></script> #有時引用的cookie.js文件沒有效果,那就換成 cdn 引用 7.url路由分發與url反向解析 根路徑配置: url(r^$, views.index), url是ip+端口時,沒有路徑,執行index視圖函數 路由分發: ‘‘‘ Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url() ‘‘‘ from django.conf.urls import url, include url(r^blog/,include(blog.urls)), 反向解析: url(r^(?P<user>.*)/$,views.person_site,name=aaa), <a href="{% url ‘aaa‘ request.user.username %}"></a> #註意 在url反向解析時,如需要參數就必須傳 8.首頁的左側菜單: index.html {% for site_category in site_category_list %} <div class="panel panel-success"> <div class="panel-heading site_category">{{ site_category.name }}</div> <div class="panel-body hides"> {% for obj in site_category.sitearticlecategory_set.all %} <a href="/cate/{{ obj.name }}/" style="text-decoration: none"><p>{{ obj.name }}</p></a> #在點擊相應的分類是顯示此分類的所有文章 {% endfor %} </div> </div> {% endfor %} urls.py url(r^cate/(.*)/$, views.index), views.py def index(request,*args): if args: article_list = models.Article.objects.filter(site_article_category__name=args[0]) else: article_list=models.Article.objects.all() site_category_list=models.SiteCategory.objects.all() return render(request,"index.html",{article_list:article_list,site_category_list:site_category_list}) css/js樣式: <script> $(.site_category).mouseover(function () { console.log($(this)) console.log(this) //打印兩者的區別??? $(this).next().slideDown(300) }).parent().mouseleave(function () { $(this).children(.panel-body).slideUp(300) }) </script> 9.頭像圖片在頁面中顯示的兩種方式: <img src="/media/{{ user.user.avatar }}" width="60px" height="60px"> <img src="{{ user.user.avatar.url }}" width="60px" height="60px"> 10. media配置: settings.py MEDIA_ROOT=os.path.join(BASE_DIR,"blog","media","uploads") MEDIA_URL="/media/" urls.py url(r^media/(?P<path>.*)$, serve, {document_root: settings.MEDIA_ROOT}), 用處: ----- avatar = models.FileField(verbose_name=頭像, upload_to=avatar, default="/avatar/default.png") 會把接收的文件放在media指代的路徑與upload_to的拼接: BASE_DIR/blog/media/uploads/avatar/ xxx圖片 avatar字段在數據庫保存的是:avatar/a.png ------ 在頁面中顯示 <img src="/media/avatar/a.png"> 11. auth模塊: http://www.cnblogs.com/liuwei0824/p/7772525.html 12. 個人首頁: 時間歸檔: date_list=models.Article.objects.filter(user=user_obj).extra(select={"filter_create_date":"strftime(‘%%Y/%%m‘,create_time)"}).values_list( "filter_create_date").annotate(Count("nid")) 園齡:自定義過濾器用當前的時間對象-創建的時間對象 註意:在引用自定義過濾器時 要在body標簽下 其他位置瀏覽器會出現小錯誤 標簽與分類歸檔有兩種方式處理: 1. 在後端用分組聚合函數處理完成傳入前端直接渲染 2. 在後端把文章對象傳給前端,在前端深度查詢進行渲染 13. 評論樹: views.py def commentTree(request,article_id): time_dict={} avatar_dict={} comment_all=models.Comment.objects.filter(article_id=article_id) for i in comment_all: avatar=/media/+str(i.user.avatar) time=str(i.create_time).split(.,1)[0][:-3] time_dict[i.nid]=time avatar_dict[i.nid]=avatar comment_list=models.Comment.objects.filter(article_id=article_id).values(nid,user__username,user__avatar,content,parent_comment_id) for i in comment_list: if i[nid] in time_dict: i[create_time]=time_dict[i[nid]] if i[nid] in time_dict: i[create_user_avatar] = avatar_dict[i[nid]] i[children_list] = [] d = {} for i in comment_list: d[i[nid]] = i for i in comment_list: if i[parent_comment_id] in d: d[i[parent_comment_id]][children_list].append(i) li = [] for i, j in d.items(): if not j[parent_comment_id]: li.append(j) # print(li,66666666666666) import json return HttpResponse(json.dumps(li)) .html <h5>已發表評論(評論樹):</h5> <div class="comment_tree_list"> </div> $.ajax({ url:/blog/commentTree/+$.cookie(article_obj_nid), type:get, success:function (data) { var data=JSON.parse(data); <script> {# console.log(data[1]);#} var s=showCommentTree(data); $(".comment_tree_list").append(s); } }) function showCommentTree(comment_list) { // comment_list: [{"content":"1","children_list":[{}]},{"content":"2"},{"content":"3"},] var html=""; $.each(comment_list,function (i,comment_dict) { var nid=comment_dict[nid]; var val=comment_dict["content"]; var avatar=comment_dict["create_user_avatar"]; var create_time=comment_dict["create_time"]; var comment_username=comment_dict["user__username"]; var ssss=<div class="row comment_content_haed"><div><span> +<img src=+avatar+ height="25px" width="25px" style="margin-right: 5px"></span>&nbsp;&nbsp;<a href="" style="text-decoration: none" class="comment_color c1">+comment_username+</a><span style="margin-left: 10px">+create_time+</span><a title="發送站內短消息" class="sendMsg2This" href="">&nbsp;</a></div><div class="comment_content_body"><p style="margin-left: 18px">+val+</p></div><div class="tig_head" comment_pid=+nid+><a class="pull-right comment_color tig reply" style="text-decoration: none">回復</a><a class="pull-right tig comment_color" style="text-decoration: none">支持({{ comment_obj.up_count }})</a></div></div><hr style="margin-right: 60px"> var commnent_str= <div class="comment"><div class="content"><span>+ssss+</span></div>; if(comment_dict["children_list"]){ var s=showCommentTree(comment_dict["children_list"]); // [{},{}] commnent_str+=s } commnent_str+="</div>"; html+=commnent_str }); return html } </script> 14. 編輯器的防止xss攻擊:用form組件過濾出敏感的標簽及屬性 forms.py 引用xss class ArticleForm(Form): content=fields.CharField(required=True,error_messages={required:不能為空}, widget=widgets.Textarea(attrs={id:comment_content})) def clean_content(self): from blog.plugins import xss_plugin html_str=self.cleaned_data.get("content") clean_content=xss_plugin.filter_xss(html_str) self.cleaned_data["content"]=clean_content return self.cleaned_data.get("content") def filter_xss(html_str): valid_tag_list = ["p", "div", "a", "img", "html", "body", "br", "strong", "b"] valid_dict = {"p": ["id", "class"], "div": ["id", "class"]} from bs4 import BeautifulSoup soup = BeautifulSoup(html_str, "html.parser") # soup -----> document ######### 改成dict for ele in soup.find_all(): # 過濾非法標簽 if ele.name not in valid_dict: ele.decompose() # 過濾非法屬性 else: attrs = ele.attrs # p {"id":12,"class":"d1","egon":"dog"} l = [] for k in attrs: if k not in valid_dict[ele.name]: l.append(k) for i in l: del attrs[i] print(soup) return soup.decode() #默認decode 格式就是utf-8 15. 後臺管理:增刪改查.... 16. kindeditor 編輯器文本域獲取焦點 ???

blog項目知識點梳理