博客系統

 博客系統項目整理:css

 一:建立表:html

models代碼:前端

from django.db import models
from django.contrib.auth.models import AbstractUser

class UserInfo(AbstractUser):
    '''用戶信息表'''
    nid = models.AutoField(primary_key=True)
    nickname = models.CharField(max_length=32,verbose_name="暱稱",unique=True,null=True,blank=True)
    tel = models.CharField(max_length=11,  verbose_name='電話',unique=True, null=True,blank=True)
    avatar = models.FileField(verbose_name="頭像",upload_to="avatar",default="/avatar/default.png")
    create_time = models.DateTimeField(verbose_name="建立時間",auto_now_add=True)
    class Meta:
        verbose_name_plural = "用戶信息表"
    def __str__(self):
        return self.username

class Article(models.Model):
    '''
    文章表
    '''
    title = models.CharField(max_length=64,verbose_name="文章標題")
    summary = models.CharField(max_length=244, verbose_name="文章概要")
    create_time = models.DateTimeField(verbose_name="建立時間",auto_now_add=True)
    update_time = models.DateTimeField(verbose_name="修改時間",auto_now=True)
    poll_count = models.IntegerField(verbose_name="點贊數",default=0)
    comment_count = models.IntegerField(verbose_name="評論數",default=0)
    read_count = models.IntegerField(verbose_name="閱讀數",default=0)
    # is_essence = models.BooleanField(verbose_name="是否精華",default=0)
    # is_top = models.BooleanField(verbose_name="是否置頂",default=0)

    user = models.ForeignKey(to="UserInfo",verbose_name="所屬做者",null=True,blank=True)
    classify = models.ForeignKey(to="Classfication",verbose_name="所屬類別",null=True,blank=True)
    tags = models.ManyToManyField(to="Tag",through="Article2tag",through_fields=('article', 'tag'),verbose_name="所屬標籤")
    site_article_category = models.ForeignKey(to="SiteArticleCategory", null=True,verbose_name="文章分類")
    class Meta:
        verbose_name_plural = "文章表"
    def __str__(self):
        return self.title

class Article_detail(models.Model):
    '''文章細節表'''
    article = models.OneToOneField(to="Article",verbose_name="所屬文章")
    content = models.TextField(verbose_name="文章內容")

    class Meta:
        verbose_name_plural = "文章細節表"

class Tag(models.Model):
    '''標籤表'''
    name = models.CharField(max_length=32,verbose_name="標籤名")
    blog = models.ForeignKey(to="Blog",verbose_name="所屬博客")
    def __str__(self):
        return self.name
    class Meta:
        verbose_name_plural = "標籤表"

class Article2tag(models.Model):
    article = models.ForeignKey(verbose_name="文章",to="Article")
    tag = models.ForeignKey(verbose_name="標籤",to="Tag")
    class Meta:
        '''聯合惟一'''
        unique_together = [
            ("article","tag")
        ]

class Comment(models.Model):
    '''評論表'''
    time = models.DateTimeField(verbose_name="評論時間",auto_now_add=True)
    content = models.CharField(max_length=265,verbose_name="評論內容")
    up_count = models.IntegerField(default=0)
    user = models.ForeignKey(to="UserInfo",verbose_name="評論人",null=True,blank=True)
    article = models.ForeignKey(to="Article",verbose_name="評論文章",null=True,blank=True)
    farther_comment = models.ForeignKey(to="Comment",verbose_name="父級評論",null=True,blank=True)
    # farther_comment = models.ForeignKey("self",verbose_name="父級評論",null=True,blank=True)

    class Meta:
        verbose_name_plural = "評論表"

class Article_poll(models.Model):
    '''文章點贊表'''
    time = models.DateTimeField(verbose_name="點贊時間",auto_now_add=True)
    article = models.ForeignKey(to="Article",verbose_name="點贊文章",null=True,blank=True)   #一個文章能夠有多個贊
    user = models.ForeignKey(to="UserInfo",verbose_name="點贊人",null=True,blank=True)
    # is_positive = models.BooleanField(default=1,verbose_name="點贊或踩")

    class Meta:
        '''聯合惟一'''
        unique_together = ("user", "article",)
        verbose_name_plural = "文章點贊表"

class Comment_poll(models.Model):
    '''評論點贊表'''
    time=models.DateTimeField(verbose_name="點贊時間",auto_now_add=True)
    # is_positive = models.BooleanField(verbose_name="點贊或踩",default=1)
    user = models.ForeignKey(to="UserInfo",verbose_name="點贊用戶",null=True,blank=True)
    comment = models.ForeignKey(to="Comment",verbose_name="點贊所屬評論",null=True,blank=True)   #一個評論能夠有多個贊

    class Meta:
        '''聯合惟一'''
        unique_together = ("user","comment",)
        verbose_name_plural = "評論點贊表"

class Blog(models.Model):
    '''我的站點表'''
    title = models.CharField(max_length=32,verbose_name="我的博客標題")
    url = models.CharField(max_length=64,verbose_name="路徑",unique=True)
    theme = models.CharField(max_length=32,verbose_name="博客主題")
    user = models.OneToOneField(to="UserInfo", verbose_name="所屬用戶")
    class Meta:
        verbose_name_plural = "我的站點表Blog"
    def __str__(self):
        return self.title

class Classfication(models.Model):
    '''博主我的文章分類表'''
    title = models.CharField(max_length=32, verbose_name="分類標題")
    blog = models.ForeignKey(to="Blog",verbose_name="所屬博客")
    def __str__(self):
        return self.title
    class Meta:
        verbose_name_plural = "分類表"

#與文章表關聯,屬於博客全局的分類
class SiteCategory(models.Model):
    """
    博客主頁分類,父
    """
    name=models.CharField(max_length=32)
    def __str__(self):
        return self.name
    class Meta:
        verbose_name_plural = "博客主頁分類,父"

class SiteArticleCategory(models.Model):
    """
    博客主頁分類,子
    """
    name=models.CharField(max_length=32)
    site_category=models.ForeignKey("SiteCategory")
    def __str__(self):
        return self.name
    class Meta:
        verbose_name_plural = "博客主頁分類,子"
View Code

admin:python

from django.contrib import admin
# Register your models here.
from . import models
admin.site.register(models.UserInfo)
admin.site.register(models.Article)
admin.site.register(models.Article_detail)
admin.site.register(models.Tag)
admin.site.register(models.Article2tag)
admin.site.register(models.Comment)
admin.site.register(models.Article_poll)
admin.site.register(models.Comment_poll)
admin.site.register(models.Blog)
admin.site.register(models.Classfication)
admin.site.register(models.SiteCategory)
admin.site.register(models.SiteArticleCategory)
View Code

配置---引用:jquery

#配置 settings:   AUTH_USER_MODEL = "app01.UserInfo"
#引用from django.contrib.auth.models import AbstractUser

from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractUser
View Code

表關係:git

博客系統表關係整理;
                1:建立用戶信息表(UserInfo):-----------繼承了AbstractUser(配置 settings:   AUTH_USER_MODEL = "app01.UserInfo")
                                    ----------(from django.contrib.auth.models import AbstractUser)
                        主鍵(ID)
                        暱稱(nickname)
                        電話(tel)
                        郵箱(email)
                        頭像(avatar)
                        建立時間(create_time)
                2:建立文章表(Acticle)
                        文章標題(title)
                        文章概要(summary)
                        建立時間(create_time)
                        修改時間(updata_time)
                        點贊數(poll_count)
                        評論數(comment_count)
                        閱讀數(read_count)
                        做者(user)-------------------------------與信息表(Userinfo)是一對多的關係
                        所屬類別(classify)-----------------------與分類表(Classify)是一對多的關係
                        標籤(tag)--------------------------------與標籤表(Tag)是多對多的關係,過濾關係,一篇文章只能有一層與標籤的關係,不可重複。 
                        博客的類,固定字段只有選擇的權限(type_choices)
                3文章詳細表(Article_detail)
                        所屬文章(article)------------------------與文章表是(Article)是一對一的關係
                        文章內容(content)
                4標籤表(Tag)
                        標籤名(name)
                        所屬博客(blog)----------------------------與博客表是一對多的關係
                5博客和標籤的關係表(Article2tag)--------------本身建立方便後面添加字段
                        文章(article)-----------------------------與文章表(Article)是多對一的關係
                        標籤(tag)---------------------------------與標籤表(Tag)是多對一的關係
                6:評論表
                        評論時間(time)
                        評論內容(content)
                        評論人(user)------------------------------與用戶信息表(UserInfo)是多對一的關係
                        評論文章(article)-------------------------與文章表(Acticle)是多對一的關係
                        父級評論(father_comment)------------------自關聯(能夠評論別人的評論)
                7:文章點贊表(Article_poll)
                        點贊時間(time)
                        點贊文章(article)-------------------------與文章表(Acticle)是多對一的關係
                        點贊人(user)------------------------------與用戶表(UserInfo)是多對一的關係
                8:評論點贊表(Comment_poll)
                        點贊時間(time)
                        點贊用戶(user)----------------------------與用戶信息表(UserInfo)是多對一的關係
                        點贊所屬評論(comment)---------------------與評論表(Comment)是多對一的關係
                9:博客表(Blog)
                        我的博客標題(title)
                        路徑(url)
                        theme(博客主題)
                        user(所屬用戶)----------------------------與用戶信息表是(UserInfo)是一對一的關係
                10:博主我的文章分類表(Classfication)
                        分類標題(title)
                        所屬博客(blog)----------------------------與博客表是(Blog)是多對一的關係
View Code

二:登陸:ajax

 界面顯示數據庫

      

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>博客系統首頁</title>
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <style>
        .hides{ display: none; }
    </style>
</head>
<body>
<nav class="navbar navbar-inverse primary">
    <div class="container">
            <a class="navbar-brand" href="#">博客園</a>
        <div id="bs-example-navbar-collapse-9" class="collapse navbar-collapse">
            <ul class="nav navbar-nav navbar-right">
                {% if request.user.is_authenticated %}
                    <li><a href="">{{request.userinfo.uaername}}<span class="glyphicon glyphicon-user"></span></a></li>
                    <li><a href="/log_out/">註銷</a></li>
                    <li><a href="/#/">修改密碼</a></li>
                {% else %}
                    <li><a href="/login/">登陸</a></li>
                    <li><a href="/register/">註冊</a></li>
                {% endif %}
            </ul>
            <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="搜索">
            </form>
        </div>
    </div>
</nav>
<div class="container">
        <div class="row col-md-3">
            <div class="panel panel-primary">
                <div class="panel-body">
                    網站分類
                </div>
                <div class="panel-footer">
                    {% for site in site_list %}
                        <div class="panel panel-primary">
                            <div class="panel-heading cate_title">{{site.name}}</div>
                            <div class="panel-body hides">
                                {% for sitearticlecategory in site.sitearticlecategory_set.all %}
                                    <p><a href="/site/{{sitearticlecategory.name}}">{{sitearticlecategory.name}}</a></p>
                                {% endfor %}
                            </div>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <div class=" article_list">
                {% for article in article_list %}
                    <div><a href="">{{article.title}}</a></div>
                    <div class="row">
                        <div class="avatar col-md-2">
                            <a href="{% url 'aaa'  article.user.username %}"><img src="{{article.user.avatar.url}}" alt="" width="80px" height="80px"></a>
                        </div>
                        <div class="summary col-md-10" >
                            <p>{{article.summary}}</p>
                        </div>
                    </div>
                    <div class="article_info row">
                        &nbsp&nbsp<a href="/app01/{{ article.user.username }}"><b>{{article.user.username}}</b></a> &nbsp&nbsp發佈與:{{article.create_time|date:"Y-m-d H:i"}}
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-comment"></span>評論({{article.comment_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-thumbs-up"></span>點贊({{article.poll_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-share-alt"></span>閱讀({{article.read_count}})</a>
                    </div>
                    <hr>
                {% endfor %}
            </div>
        </div>
        <div class="col-md-3">
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
        </div>
    </div>
<script>
     $(".cate_title").mouseover(function () {
        $(this).next().slideDown(300)
    }).parent().mouseleave(function () {
         $(this).children(".panel-footer").slideUp(300)
     });
{#    $(".cate_title").mouseenter(function () {#}
{#        $(this).next().slideDown(300)#}
{#    });#}
{#    $(".panel-footer").mouseleave(function () {#}
{#        $(this).next().slideUp(300)#}
{#    });#}
</script>
</b

導入:django

 urljson

url(r'^get_authCode_img/', views.get_authCode_img),
    url(r'^login/$',views.login),

 

前端頁面的實現:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>博客系統首頁</title>
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <style>
        .hides{ display: none; }
    </style>
</head>
<body>
<nav class="navbar navbar-inverse primary">
    <div class="container">
            <a class="navbar-brand" href="#">博客園</a>
        <div id="bs-example-navbar-collapse-9" class="collapse navbar-collapse">
            <ul class="nav navbar-nav navbar-right">
                {% if request.user.is_authenticated %}
                    <li><a href="">{{request.userinfo.uaername}}<span class="glyphicon glyphicon-user"></span></a></li>
                    <li><a href="/log_out/">註銷</a></li>
                    <li><a href="/#/">修改密碼</a></li>
                {% else %}
                    <li><a href="/login/">登陸</a></li>
                    <li><a href="/register/">註冊</a></li>
                {% endif %}
            </ul>
            <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="搜索">
            </form>
        </div>
    </div>
</nav>
<div class="container">
        <div class="row col-md-3">
            <div class="panel panel-primary">
                <div class="panel-body">
                    網站分類
                </div>
                <div class="panel-footer">
                    {% for site in site_list %}
                        <div class="panel panel-primary">
                            <div class="panel-heading cate_title">{{site.name}}</div>
                            <div class="panel-body hides">
                                {% for sitearticlecategory in site.sitearticlecategory_set.all %}
                                    <p><a href="/site/{{sitearticlecategory.name}}">{{sitearticlecategory.name}}</a></p>
                                {% endfor %}
                            </div>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <div class=" article_list">
                {% for article in article_list %}
                    <div><a href="">{{article.title}}</a></div>
                    <div class="row">
                        <div class="avatar col-md-2">
                            <a href="{% url 'aaa'  article.user.username %}"><img src="{{article.user.avatar.url}}" alt="" width="80px" height="80px"></a>
                        </div>
                        <div class="summary col-md-10" >
                            <p>{{article.summary}}</p>
                        </div>
                    </div>
                    <div class="article_info row">
                        &nbsp&nbsp<a href="/app01/{{ article.user.username }}"><b>{{article.user.username}}</b></a> &nbsp&nbsp發佈與:{{article.create_time|date:"Y-m-d H:i"}}
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-comment"></span>評論({{article.comment_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-thumbs-up"></span>點贊({{article.poll_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-share-alt"></span>閱讀({{article.read_count}})</a>
                    </div>
                    <hr>
                {% endfor %}
            </div>
        </div>
        <div class="col-md-3">
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
        </div>
    </div>
<script>
     $(".cate_title").mouseover(function () {
        $(this).next().slideDown(300)
    }).parent().mouseleave(function () {
         $(this).children(".panel-footer").slideUp(300)
     });
{#    $(".cate_title").mouseenter(function () {#}
{#        $(this).next().slideDown(300)#}
{#    });#}
{#    $(".panel-footer").mouseleave(function () {#}
{#        $(this).next().slideUp(300)#}
{#    });#}
</script>
</body>
</
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>用戶登陸頁面</title>
    <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="/static/css/login.css">
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row col-md-4 col-lg-offset-4 container">
        <form method=post>
                {% csrf_token %}
                <h1 class="form-signin-heading col-lg-offset-4 text-primary"><b>請登陸:</b></h1>
                 <hr>
                <div>
                    <label for="username">用戶名:</label>
                    <p class="username"><input id="username" class="form-control" placeholder="用戶名"  type="text" name="username"></p>
                </div>
                <div>
                    <label for="password">密碼:</label>
                    <p class="password"><input id="password" class="form-control" placeholder="密碼"  type="password" name="password"></p>
                </div>
                <div>
                    <label for="auth_code">驗證碼:</label>
                    <p class="auth_code"><input id="auth_code" class="form-control" placeholder="驗證碼"  type="text" name="auth_code"></p>
                </div>
                <div>
                    <img class="auth_code_img" src="/get_authCode_img/" style="width:200px;height:50px">
{#                    <a class="refresh">看不清</a>#}
                </div>
            <hr>
            <input type="button" value="登陸" class="btn btn-lg btn-primary pull-left" id="subBtn"><span class="error"></span>
            <a href="/register/"> <input type="button" value="註冊" class="btn btn-lg btn-primary pull-right" id=""></a>
        </form>
    </div>
</div>
<script>
    //登陸
   $("#subBtn").click(function () {
       $.ajax({
           url:"/login/",
           type:"POST",
           data:{
               "username":$("#username").val(),
               "password":$("#password").val(),
               "auth_code":$("#auth_code").val(),
               "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()
           },
           success:function (data) {
               console.log(data);
               var response=JSON.parse(data);
               if (response["is_login"]){
                   location.href="/index/"
               }
               else {
                    $(".error").html(response["error_msg"]).css("color","red")
               }
           }
       })
   });
    // 驗證碼刷新
    $(".auth_code_img").click(function () {
        $(this)[0].src+="?"
    })
</script>
</body>
</html>
View Code

後端代碼:

 登陸
def login(request):
    if request.is_ajax():
        login_response = {"is_login": False, "error_msg": None}  # 定義一個字典
        username = request.POST.get("username")  # 取到用戶名
        password = request.POST.get("password")  # 取到密碼
        auth_code = request.POST.get("auth_code")  # 取到驗證碼
        if auth_code.upper() == request.session.get("auth_code").upper():  # 從session中獲取驗證碼,判斷是否正確
            # print(username, password, '==========')
            user = auth.authenticate(username=username, password=password)
            print(user)  # 經過auth模塊獲取用戶名密碼
            if user:  # 正確,判斷用戶名和密碼是否正確
                login_response["is_login"] = True
                auth.login(request, user)
            else:
                login_response["error_msg"] = "用戶名或密碼不正確"  # 前端顯示用戶名或密碼錯誤
        else:
            login_response["error_msg"] = '驗證碼不正確'  # 前端顯示驗證碼錯誤
        return HttpResponse(json.dumps(login_response))  # 返回
    return render(request, "login.html")  # 若不是Ajax訪問方式,返回登陸頁面從新登陸
View Code

驗證碼:

# 登陸
def login(request):
    if request.is_ajax():
        login_response = {"is_login": False, "error_msg": None}  # 定義一個字典
        username = request.POST.get("username")  # 取到用戶名
        password = request.POST.get("password")  # 取到密碼
        auth_code = request.POST.get("auth_code")  # 取到驗證碼
        if auth_code.upper() == request.session.get("auth_code").upper():  # 從session中獲取驗證碼,判斷是否正確
            # print(username, password, '==========')
            user = auth.authenticate(username=username, password=password)
            print(user)  # 經過auth模塊獲取用戶名密碼
            if user:  # 正確,判斷用戶名和密碼是否正確
                login_response["is_login"] = True
                auth.login(request, user)
            else:
                login_response["error_msg"] = "用戶名或密碼不正確"  # 前端顯示用戶名或密碼錯誤
        else:
            login_response["error_msg"] = '驗證碼不正確'  # 前端顯示驗證碼錯誤
        return HttpResponse(json.dumps(login_response))  # 返回
    return render(request, "login.html")  # 若不是Ajax訪問方式,返回登陸頁面從新登陸
View Code

驗證碼刷新:

// 驗證碼刷新
    $(".auth_code_img").click(function () {
        $(this)[0].src+="?"
    })
View Code

註銷:

#註銷
def log_out(request):
    auth.logout(request)
    return redirect("/login/")
View Code

css代碼:

.container{
    margin-top:20px;
  }
View Code

請求流程:

 

流程:

1:客戶端-----------發送(第一次get請求)-------------客戶端返回一個Html頁面(登陸頁面)
2:驗證碼-----------src(url再次請求服務端)----------服務端執行驗證碼函數,生成驗證碼保存在session中
3:用戶輸入內容----點擊提交發送ajax請求---(Post)----服務端從request中拿到ajax請求信息。
4:從session中取出取出驗證碼和--ajax中的信息進行匹配。
5:匹配成功---------進行下一步驗證,失敗返回錯誤信息,在Html頁面渲染。
6:經過auth模塊獲取用戶名密碼,判斷用戶名和密碼是否和數據庫中的相同。
7:若相同,寫入定義的字典中。
	一「is_login」:true-----保存在session中,跳轉到首頁
8:若不相同,返回登陸頁面,渲染錯誤信息。
              1,用ajax提交數據 $(".log_btn").click(function(){ $.ajax({ url:url路徑 type:訪問狀態 headers: {"X-CSRFToken":
                  $.cookie('csrftoken')},#跨站請求訪問 返回的數據 data:{ 字典名:$(".字段標識名").val() } 接收數據 sussecc:funsess(data){ 函數 } }) }
              二、圖片刷新(寫在sussecc函數中) 原理:給圖片綁定一個點擊事件:每次給src+?就會再次發送一次get請求,就起到了刷星的做用 dom對象 $(".validCode_img")
                  .click(function () { $(this)[0].src+="?";

隨機驗證碼:

    方式一:將圖片導入靜態文件,用文件句柄打開圖片返回給前端進行渲染
    方式二:導入PIL模塊,利用Image生成一張圖片保存後,用文件舉兵打開,返回前端
    方式三:導入PIL、IO模塊,仍是利用Image生成圖片,可是此次沒有將圖片保存到磁盤而是將圖片利用IO模塊中的BytesIO暫時的保存到內存中,用BytesIO句柄打開,返回到前端。
    方式四:對方式三進行優化,加上了random模塊可讓圖片隨機生成,加上隨機的5個字符,基本的驗證碼就顯示出來了
 驗證原理:
由於隨機碼是用for循環生成的先將它放入一個列表中,人後將列表轉換
爲字符串,存入session中便於作對比,接收前端發過來的數據,包括用
戶名密碼以及驗證碼三條數據,先拿session中保存的驗證碼與前段發來
的驗證碼進行匹配驗證,若是匹配成功則進行用戶名密碼的匹配匹配成功
則登陸成功
 
 代碼: 
def get_authCode_img(request):
    #方式一
    # import os
    # path = os.path.join(settings.BASE_DIR, "static", "img", "a.jpg")
    # with open(path, "rb") as f:
    #     data = f.read()
    # return HttpResponse(data)
    # 方式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()
    # return HttpResponse(data)
    # 方式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("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["Keep_auth_code"]=valid_str   #將驗證碼寫入session中
    return HttpResponse(data)
View Code

 

三:註冊:

  頁面

 

 

 

form組件:

#! usr/bin/env python
# -*- coding: utf-8 -*-
from django import forms
from django.forms import fields
from django.forms import widgets,ValidationError
from app01 import models
from django.core.validators import RegexValidator
class RegisterForm(forms.Form):
    """註冊Form組件"""
    username = forms.CharField(
        required=True,
        min_length=3,
        max_length=8,
        error_messages={
            'required': '用戶不能爲空',
            'min_length': '用戶長度不能小於3',
            'max_length': '用戶長度不能大於8',
        },widget=widgets.TextInput(attrs={'placeholder': '用戶名:', 'class': 'form-control'}))
    password = fields.CharField(
        required=True,
        min_length=3,
        max_length=8,
        error_messages={
            'required': '密碼不能爲空',
            'min_length': '密碼長度不能小於3',
            'max_length': '密碼長度不能大於8',
            # 'invalid': '密碼格式錯誤',
        },
        # validators=[RegexValidator('\d+', '只能是數字')],
        widget=widgets.PasswordInput(attrs={'placeholder': '密碼:', 'class': 'form-control'}))
    confirm_password = fields.CharField(
        required=True,
        min_length=3,
        max_length=8,
        error_messages={
            'required': '確認密碼不能爲空',
            'min_length': '確認密碼長度不能小於3',
            'max_length': '確認密碼長度不能大於8',
        },
        widget=widgets.PasswordInput(attrs={'placeholder': '確認密碼:', 'class': 'form-control'}))

    email = fields.EmailField(
        required=True,
        error_messages={
            'required':'郵箱不能爲空',
            'invalid':'郵箱格式錯誤'},
        widget=widgets.EmailInput(attrs={'placeholder':'郵箱:','class':'form-control'}))


    def clean_username(self):
        """用戶名"""
        ret = models.UserInfo.objects.filter(username=self.cleaned_data.get("username"))
        if not ret:
            return self.cleaned_data.get("username")
        else:
            raise ValidationError("用戶名已註冊")

    def clean_password(self):
        """密碼"""
        data = self.cleaned_data.get("password")
        if not data.isdigit():
            return self.cleaned_data.get("password")
        else:
            raise ValidationError("密碼不能全是數字")

    # def clean_auth_code(self):
    #     if self.cleaned_data.get("auth_code")==self.request.session.get("auth_code"):
    #         return self.cleaned_data.get("auth_code")
    #     else:
    #         raise ValidationError("驗證碼錯誤")

    def clean(self):
        if self.cleaned_data.get("password")==self.cleaned_data.get("confirm_password"):
             return self.cleaned_data
        else:
            raise ValidationError("兩次密碼不一致")

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request=request
View Code

前端頁面顯示:

from django.shortcuts import render, HttpResponse, redirect
from app01.forms import *
from app01 import forms
from app01 import models
from django.db.models import Count
import json
from django.contrib import auth
# 登陸
def login(request):
    if request.is_ajax():
        login_response = {"is_login": False, "error_msg": None}  # 定義一個字典
        username = request.POST.get("username")  # 取到用戶名
        password = request.POST.get("password")  # 取到密碼
        auth_code = request.POST.get("auth_code")  # 取到驗證碼
        if auth_code.upper() == request.session.get("auth_code").upper():  # 從session中獲取驗證碼,判斷是否正確
            # print(username, password, '==========')
            user = auth.authenticate(username=username, password=password)
            print(user)  # 經過auth模塊獲取用戶名密碼
            if user:  # 正確,判斷用戶名和密碼是否正確
                login_response["is_login"] = True
                auth.login(request, user)
            else:
                login_response["error_msg"] = "用戶名或密碼不正確"  # 前端顯示用戶名或密碼錯誤
        else:
            login_response["error_msg"] = '驗證碼不正確'  # 前端顯示驗證碼錯誤
        return HttpResponse(json.dumps(login_response))  # 返回
    return render(request, "login.html")  # 若不是Ajax訪問方式,返回登陸頁面從新登陸
# 驗證碼
def get_authCode_img(request):
    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("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["auth_code"] = valid_str  # 將驗證碼寫入session中
    return HttpResponse(data)
#註銷
def log_out(request):
    auth.logout(request)
    return redirect("/login/")
# 註冊
def register(request):
    if request.is_ajax():
        form_obj = forms.RegisterForm(request,request.POST)
        print("---------")
        print(form_obj.is_valid())
        regResponse = {"user": None, "errorsList": None}
        if form_obj.is_valid():
            print("000000")
            username = form_obj.cleaned_data["username"]
            password = form_obj.cleaned_data["password"]
            # nickname = form_obj.cleaned_data["nickname"]
            # tel = form_obj.cleaned_data["tel"]
            email = form_obj.cleaned_data.get("email")
            avatar_img = request.FILES.get("avatar_img")
            user_obj = models.UserInfo.objects.create_user(username=username, password=password,email=email,avatar=avatar_img)
            regResponse["user"] = user_obj.username
        else:
            print("111")
            regResponse["errorsList"] = form_obj.errors
            print(regResponse)
        return HttpResponse(json.dumps(regResponse))
    form_obj= forms.RegisterForm(request)
    return render(request, "register.html", {"form_obj": form_obj})
# 主頁
def index(request,*args,**kwargs):
    if kwargs:
        article_list = models.Article.objects.filter(site_article_category__name=kwargs.get("site_article_category"))#查找點擊的類的文章
    else:
        article_list = models.Article.objects.all()
    site_list = models.SiteCategory.objects.all()
    return render(request, "index.html",{"article_list":article_list,"site_list":site_list})
#我的主頁
def homeSite(request,username,**kwargs):
    # print(kwargs)
    # print(username)
    """點擊文章用戶名或,頭像跳轉的此頁"""
    current_user = models.UserInfo.objects.filter(username=username).first()#獲取當前用戶
    # current_blog = current_user.blog#獲取當前博客
    if not current_user:
        return render(request,"notFound.html")
    current_blog = current_user.blog  # 獲取當前博客
    #查詢當前文章
    article_list=models.Article.objects.filter(user=current_user)
    #查詢 當前用戶的分類歸檔
    classfication_list=models.Classfication.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("title","c")
    #查詢當前用戶的標籤歸檔
    tag_list=models.Tag.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("name","c")
    #查詢當前用戶的標籤歸檔
    date_list = models.Article.objects.filter(user=current_user).extra(
        select={"filter_create_date": "strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(Count("id"))
    if kwargs:
        if kwargs.get("condition")=="classify":
            print(kwargs.get("condition"))
            article_list = models.Article.objects.filter(user=current_user,classify__title=kwargs.get("para"))
            # article_list = models.Article.objects.filter(user=current_user, category__title=kwargs.get("para"))
        elif kwargs.get("condition")=="tag":
            article_list = models.Article.objects.filter(user=current_user,tags__name=kwargs.get("para"))
        elif kwargs.get("condition")=="date":
            year,month=kwargs.get("para").aplit("/")
            article_list = models.Article.objects.filter(user=current_user,create_time__year=year,create_time__month=month)
    return render(request,"homeSite.html", locals())

#具體文章詳細
def contentsArticle(request,username,article_id):
    """點擊文章標題,跳轉到此頁"""
    current_user = models.UserInfo.objects.filter(username=username).first()  # 獲取當前用戶
    current_blog = current_user.blog#獲取當前博客
    if not current_user:
        return render(request, "notFound.html")
    # 查詢當前文章
    article_list = models.Article.objects.filter(user=current_user)
    # 查詢 當前用戶的分類歸檔
    classfication_list = models.Classfication.objects.all().filter(blog=current_blog).annotate(
        c=Count("article__id")).values_list("title", "c")
    # 查詢當前用戶的標籤歸檔
    tag_list = models.Tag.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("name",
                                                                                                               "c")
    # 查詢當前用戶的標籤歸檔
    date_list = models.Article.objects.filter(user=current_user).extra(
        select={"filter_create_date": "strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(
        Count("id"))
    article_obj = models.Article.objects.filter(id=article_id).first()
    return render(request,"contents_article.html",loca
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>用戶註冊頁面</title>
    <link href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/css/register.css" rel="stylesheet">
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/js/jquery.cookie.js"></script>
</head>
<body>
<div class="container">
    <div class="row col-md-4 col-lg-offset-4">
        <form>
            {% csrf_token %}
            <h2 class="form-signin-heading col-lg-offset-3 text-info">請您註冊:</h2>
            <div class="form-group">
                <label for="username">用戶名:</label>
                <p>{{ form_obj.username }} {{ form_obj.errors.username.0 }}</p>
            </div>
            <div class="form-group">
                <label for="password">密碼:</label>
                <p>{{ form_obj.password }} {{ form_obj.errors.password.0 }}</p>
            </div>
            <div class="form-group">
                <label for="confirm_password">確認密碼:</label>
                <p>{{ form_obj.confirm_password }} {{ form_obj.errors.confirm_password.0 }}</p>
            </div>
{#            <div class="form-group">#}
{#                <label for="nickname">暱稱:</label>#}
{#                <p>{{ form_obj.nickname }} {{ form_obj.errors.nickname.0 }}</p>#}
{#            </div>#}
{#            <div class="form-group">#}
{#                <label for="tel">電話:</label>#}
{#                <p>{{ form_obj.tel }} {{ form_obj.errors.tel.0 }}</p>#}
{#            </div>#}
            <div class="form-group">
                <label for="email">郵箱:</label>
                <p>{{ form_obj.email }} {{ form_obj.errors.email.0 }}</p>
            </div>
            <div class="form-group avatar">
                 <label for="avatar">頭像</label>
                 <img src="/static/img/default.png" alt="" id="avatar_img">
                 <input type="file" id="avatar_file">
            </div >
            <div class="col-lg-offset-5">
                <input type="button" value="提交" class="btn btn-primary" id="avatar_Btn"><span class="error"></span>
            </div>
        </form>
    </div>
</div>
<script>
    $("#avatar_file").change(function () {
        //頭像預覽
    var ele_file = $(this)[0].files[0];
    var reader = new FileReader();
    reader.readAsDataURL(ele_file);
    reader.onload = function () {
        $("#avatar_img")[0].src = this.result
    }
});

    $("#avatar_Btn").click(function () {
    var formdata = new FormData();
    formdata.append("username", $("#id_username").val());
    formdata.append("password", $("#id_password").val());
    formdata.append("confirm_password", $("#id_confirm_password").val());
{#    formdata.append("nickname", $("#id_nickname").val());#}
{#    formdata.append("tel", $("#id_tel").val());#}
    formdata.append("email", $("#id_email").val());
    formdata.append("avatar_img",$("#id_avatar_img").val());
    $.ajax({
        url: "/register/",
        type: "POST",
        data: formdata,
        contentType: false,
        processData: false,
        headers:{"X-CSRFToken":$.cookie('csrftoken')},

        success: function (data) {
            console.log(data);
            var data = JSON.parse(data);
            if (data.user) {
                location.href = "/login/"
            }


            //全局鉤子的錯誤提示
            else {
                    console.log(data.errorsList);
                     $(".pull-right").html("").parent().removeClass("has-error");//去除第一次錯誤信息
                       $.each(data.errorsList,function (i,j) {
                       console.log(i,j);
                       $span=$("<span>");
                       $span.addClass("pull-right").css("color","red");//給錯誤信息添加一個紅色
                       $span.html(j[0]);
                       $("#id_"+i).after($span).parent().addClass("has-error");//找到當前錯誤的input框
                       if (i=="__all__"){
                            $("#id_confirm_password").after($span)
                       }
                   })
                }
            }
        })
    })
</script>
</body>
</html>
View Code

後端代碼:

def register(request):
    if request.is_ajax():
        form_obj = forms.RegisterForm(request,request.POST)
        print("---------")
        print(form_obj.is_valid())
        regResponse = {"user": None, "errorsList": None}
        if form_obj.is_valid():
            print("000000")
            username = form_obj.cleaned_data["username"]
            password = form_obj.cleaned_data["password"]
            # nickname = form_obj.cleaned_data["nickname"]
            # tel = form_obj.cleaned_data["tel"]
            email = form_obj.cleaned_data.get("email")
            avatar_img = request.FILES.get("avatar_img")
            user_obj = models.UserInfo.objects.create_user(username=username, password=password,email=email,avatar=avatar_img)
            regResponse["user"] = user_obj.username
        else:
            print("111")
            regResponse["errorsList"] = form_obj.errors
            print(regResponse)
        return HttpResponse(json.dumps(regResponse))
    form_obj= forms.RegisterForm(request)
    return render(request, "register.html", {"form_obj": form_obj})
View Code

css代碼:

.container{
    margin-top:50px;
  }

.avatar{
    position: relative;
    width: 60px;
    height: 60px;
}
#avatar_img,#avatar_file{
    position: absolute;
    top:0;
    left: 40px;
    width: 60px;
    height: 60px;
}
#avatar_file{
    opacity: 0;
}
View Code

頭像預覽JS:

/**
 * Created by pc on 2017-11-21.
 */
//頭像預覽
$("#avatar_file").change(function () {
    var ele_file = $(this)[0].files[0];
    var reader = new FileReader();
    reader.readAsDataURL(ele_file);
    reader.onload = function () {
        $("#avatar_img")[0].src = this.result
    }
});
$("#avatar_Btn").click(function () {
    var formdata = new FormData();
    formdata.append("username", $("#id_username")).val();
    formdata.append("password", $("#id_password")).val();
    formdata.append("confirm_password", $("#id_confirm_password")).val();
    formdata.append("nickname", $("#id_nickname")).val();
    formdata.append("tel", $("#id_tel")).val();
    formdata.append("email", $("#id_email")).val();
    formdata.append("avatar_img",$("#id_avatar_img")).val();
    $.ajax({
        url: "/register/",
        type: "POST",
        data: formdata,
        contentType: false,
        processData: false,
        header: {"X-CSRFToken": $.cookie('csrftoken')},
        success: function (data) {
            console.log(data);
            var data = JSON.parse(data);
            if (data.user) {
                location.href = "/login/"
            }
            else {
                console.log(data.errorsList);
                $.each(data.errorsList, function (i, j) {
                    console.log(i, j);
                    $span = $("<span>");
                    $span.addClass("pull-right").css("color", "red");
                    $span.html(j[0]);
                    $("#id_" + i).after($span).parent().addClass("has-error");
                    if (i=="__all__") {
                        $("#id_repeat_pwd").after($span)
                    }
                })
            }
        }
    })
});
View Code

settings配置:

AUTH_USER_MODEL = "app01.UserInfo"

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,"static"),
]
MEDIA_ROOT=os.path.join(BASE_DIR,"app01","media","uploads")
MEDIA_URL="/media/"
View Code

流程:

註冊
    1. form組件生成html標籤 
        在RegFrom類中繼承From這個類,
        利用這個類的方法,生成input標籤,在這個類中可設置,標籤的屬性
        - username
        - password
        - email
    2. 利用後端傳來的form在前端生成html標籤
        第一次get請求時後返回RegFrom類實例化的對象,
            前端生成- username,- password,- emai,- avatar對應的四個標籤
             
            顯示圖片:
            - 圖片和上傳文件摺疊
                - 做用:上傳文件覆蓋圖片,透明度爲零 用戶點擊圖片其實點擊上傳文件
                -- 把上傳文件和圖片的父親標籤設置爲相對路徑 設置長寬,本身
            - 圖片預覽
                - 用戶點擊上傳文件 上傳文件的標籤發生變化,會觸發change事件
                - 取到用戶上傳的文件  var ele_file = this.files[0]; 
                - 建立FileReader()對象4
                - 把上傳文件的對象的路徑寫入FileReader()對象,結果爲FileReader().result
                - FileReader()加載onload事件,把FileReader().result結果寫入到img標籤
 
    3. 用戶提交數據
          
          用戶經過ajav提交數據:
          若是要傳二進制的數據必需要用FormData打包
                 在傳二進制的時候必需要到的參數
                         -------contentType:false,
                         ------processData:false,
                         -----headers:{"X-CSRFToken":$.cookie('csrftoken')},防止跨站請求     
               --用FormData打包數據
                  var formdata=new FormData();
                      formdata.append("username",$("#id_username").val());
                --經過data把數據傳到後臺函數
 
                 
    4.驗證數據
         post請求走Regfrom函數
             -有錯誤利用RegForm 的鉤子返回錯誤,----》
                    有錯誤將錯誤信息用鍵值對保存到errorst中
                    沒有錯誤將前端拿到的數據放入cleaned_data中
                註冊函數中判斷form_obj.is_valid對象是否正確
                    ---正確則獲取數據寫入數據庫---返回一個狀態 regResponse["user"]=user_obj.username-----給前端
                    ---錯誤則獲取數據寫入數據庫---返回一個狀太regResponse["errorsList"]=form_obj.errors-----給前端
                  
              
         後臺函數利用form_obj.cleaned_data拿到數據
    5、前端用ajax接收處理錯誤信息
                       $.each(data.errorsList,function (i,j) {
{#                       controls.log(data.errorsList)#}
{#                       console.log(i,j);#}
                             //   i           j
                        ------- username ["用戶名不能爲空"]
                        ------- password ["密碼不能爲空"]
                        -------  repeat_pwd ["驗證密碼不能爲空"]
                        -------  email ["郵箱不能爲空"]
                       $span=$("<span>");
                       $span.addClass("pull-right").css("color","red");
                        --------{# 添加一個span標籤#}
                       $span.html(j[0]);
                        --------{#把log的值j寫入span中#}
                       $("#id_"+i).after($span).parent().addClass("has-error")
                       -------#id_"+i找到當前的錯誤的input框
                       -------parent().addClass("has-error")給錯誤的input框加一個紅色的顏色
                       if (i=="__all__"){
                            $("#id_repeat_pwd").after($span)
                        -------全局鉤子的錯誤信息
                       }
                   })
View Code

 

  四:博客主頁:

頁面:

 

前端代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>{{username}}博客首頁</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <link rel="stylesheet" href="/static/css/homeSite.css">
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="MenuBar">
        <div class="heeder">
            <div class="leftbutton">
                    <span class="abuttn">{{current_user.username}}</span>
                    <a href="" class="abuttn">博客園</a>
            </div>
            <div class="key-search">
                <form action="/" method="post">
                    <a href="#" class="i">
                        <span class="ico"></span>
                    </a>
                </form>
            </div>
            <div class="rightbutton">
                <a href="" class="abuttn">首頁</a>
                <a href="" class="abuttn">新隨筆</a>
                <a href="" class="abuttn">聯繫</a>
                <a href="" class="abuttn">訂閱</a>
                <a href="" class="abuttn">管理</a>
            </div>
        </div>
    </div>
    <div class="container homeSite">
        <div class="row">
            <div class="col-md-3 userinfo">
                <div class="well well-lg ">
                    <h4 class="col-lg-offset-3">我的信息</h4>
                    <p>---------------------------------------------</p>
                    <p><img src="{{current_user.avatar.url}}" alt="" width="100px" height="100px" class="img-circle"></p>
                    <p>暱稱:&nbsp&nbsp&nbsp&nbsp<span>{{current_user.username}}</span></p>
                    <p>園齡:</p>
                    <p>粉絲:</p>
                    <p>關注:</p>
                    <a href="">+關注</a>
                </div>
                <div class="panel panel-primary">
                    <div class="panel-heading"><b>分類歸檔</b></div>
                    <div class="panel-body">
                        {% for classfication in classfication_list %}
                            <p><a href="/app01/{{ current_user.username }}/classify/{{classfication.0}}">{{classfication.0}}({{classfication.1}})</a></p>
{#                            <p>{{ classfication }}</p>#}
                        {% endfor %}
                    </div>
                    <div class="panel-heading"><b>標籤歸檔</b></div>
                    <div class="panel-body">
                        {% for tag in tag_list %}
                            <p><a href="/app01/{{current_user.username}}/tag/{{tag.0}}">{{tag.0}}({{tag.1}})</a></p>
                        {% endfor %}


                    </div>
                    <div class="panel-heading"><b>日期歸檔</b></div>
                    <div class="panel-body">
                        {% for date in date_list %}
                            <p><a href="/app01/{{current_user.username}}/date/{{date.0}}">{{date.0}}({{date.1}})</a></p>
                        {% endfor %}
                    </div>
                </div>
            </div>
{#            文章#}
            <div class="col-md-9 articleinfo">
            {% block content %}
                {% for article in article_list %}
                        <div class="well well-lg ">
                            <div class="col-lg-offset-9">
                                <h4>{{article.create_time|date:"Y年m月d日"}}</h4>
                            </div>
                            <p>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------</p>
                            <h3><a href="/app01/{{current_user.username}}/article/{{article.id}}"><b>{{article.title}}</b></a></h3>
                            <hr>
                            <div class="summary">
                                <p>{{article.summary}}<span><a href="">閱讀全文</a></span></p>
                            </div>
                            <hr>
                            <div class="col-lg-offset-5 info">
                                發表於:<span>{{article.create_time|date:"Y-m-d  H:i"}}</span>
                                &nbsp&nbsp評論:<span>({{article.comment_count}})</span>
                                &nbsp&nbsp點贊:<span>({{article.poll_count}})</span>
                                &nbsp&nbsp閱讀:<span>({{article.read_count}})</span>
                                &nbsp&nbsp&nbsp&nbsp<span><a href="">編輯</a></span>
                            </div>
                        </div>
                    {% endfor %}
            {% endblock %}

            </div>
        </div>
    </div>
</body>
</html>
View Code

後端代碼:

def index(request,*args,**kwargs):
    if kwargs:
        article_list = models.Article.objects.filter(site_article_category__name=kwargs.get("site_article_category"))#查找點擊的類的文章
    else:
        article_list = models.Article.objects.all()
    site_list = models.SiteCategory.objects.all()
    return render(request, "index.html",{"article_list":article_list,"site_list":site_list})
View Code

            1:在url中寫主頁路由
                url(r'^index', views.index)

url(r'^index', views.index),#主頁                

            2:建立視圖函數,從數據庫取出數據,返回到前端。
                -------找到文章表,取出文章對象,返回。
                
                -------找到網站分類表,取出分類對象,返回。

def index(request,*args,**kwargs):
    if kwargs:
        article_list = models.Article.objects.filter(site_article_category__name=kwargs.get("site_article_category"))#查找點擊的類的文章
    else:
        article_list = models.Article.objects.all()
    site_list = models.SiteCategory.objects.all()
    return render(request, "index.html",{"article_list":article_list,"site_list":site_list})

               
            3:返回到主頁html進行渲染:
            
                1:-----拿到文章對象用for標籤循環,{{.文章內容}}進行渲染。
                

<div class="col-md-6">
            <div class=" article_list">
                {% for article in article_list %}
                    <div><a href="">{{article.title}}</a></div>
                    <div class="row">
                        <div class="avatar col-md-2">
                            <a href="{% url 'aaa'  article.user.username %}"><img src="{{article.user.avatar.url}}" alt="" width="80px" height="80px"></a>
                        </div>
                        <div class="summary col-md-10" >
                            <p>{{article.summary}}</p>
                        </div>
                    </div>
                    <div class="article_info row">
                        &nbsp&nbsp<a href="/app01/{{ article.user.username }}"><b>{{article.user.username}}</b></a> &nbsp&nbsp發佈與:{{article.create_time|date:"Y-m-d H:i"}}
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-comment"></span>評論({{article.comment_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-thumbs-up"></span>點贊({{article.poll_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-share-alt"></span>閱讀({{article.read_count}})</a>
                    </div>
                    <hr>
                {% endfor %}
            </div>

 


                2:-----拿到分類對象用for標籤循環,{{.網站分類,父}}進行渲染。
                
                3:-----拿到網站分類對象,{{.(反向查詢,表名_set).網站分類,子}}進行渲染。
               

<div class="row col-md-3">
            <div class="panel panel-primary">
                <div class="panel-body">
                    網站分類
                </div>
                <div class="panel-footer">
                    {% for site in site_list %}
                        <div class="panel panel-primary">
                            <div class="panel-heading cate_title">{{site.name}}</div>
                            <div class="panel-body hides">
                                {% for sitearticlecategory in site.sitearticlecategory_set.all %}
                                    <p><a href="/site/{{sitearticlecategory.name}}">{{sitearticlecategory.name}}</a></p>
                                {% endfor %}
                            </div>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
View Code


              4:JQ作動態摺疊效果,鼠標懸浮展開,鼠標移開摺疊。
            
                    1:-----選擇器找到網站分類,給他綁定一個(懸浮)事件,當觸發這個事件(鼠標懸浮),執行function,$(this)找到選擇器對象,執行展開事件。
                
                    2:-----選擇器找到網站分類的父級,給他綁定一個(懸浮)執行function,$(this)找到選擇器對象,執行摺疊事件事件。       

$(".cate_title").mouseover(function () {
                            $(this).next().slideDown(300)
                        }).parent().mouseleave(function () {
                             $(this).children(".panel-footer").slideUp(300)
                         });

 


            5:點擊網站分類,子分類,查找到這個分類下的全部文章。
            
                -------分類渲染在<a>標籤中,給他一個url,鼠標點擊,------走urls進行路由匹配--------找url的視圖函數--------進行查找
                
                        a標籤:---------/site/{{網站分類,name}}
                        
                        url:------------以site開頭,有名分組(接收點擊的分類),按關鍵字傳參.*匹配全部,返回一個鍵值對,返回到視圖函數。
                                        url(r'^site/(?P<site_article_category>.*)/$', views.index),
                                        

url(r'^site/(?P<site_article_category>.*)/$', views.index),

 


                        視圖函數--------**kwargs接收鍵值對,判斷kwargs,判斷正確,進行網站查詢,不然查詢全部文章。
                        
                        查詢------------找到文章表,過濾(反向查詢按字段)出文章的網站分類,子分類 =kwargs傳過來的分類,返回到前端進行渲染。
                                    article_list = models.Article.objects.filter(site_article_category__name=kwargs.get("site_article_category"))
                                   

def index(request,*args,**kwargs):
    if kwargs:
        article_list = models.Article.objects.filter(site_article_category__name=kwargs.get("site_article_category"))#查找點擊的類的文
View Code

首頁:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>博客系統首頁</title>
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <style>
        .hides{ display: none; }
    </style>
</head>
<body>
<nav class="navbar navbar-inverse primary">
    <div class="container">
            <a class="navbar-brand" href="#">博客園</a>
        <div id="bs-example-navbar-collapse-9" class="collapse navbar-collapse">
            <ul class="nav navbar-nav navbar-right">
{#                {% if request.user.is_authenticated %}#}
                    <li><a href=""><span class="glyphicon glyphicon-user">{{request.user.uaername}}</span></a></li>
                    <li><a href="/#/">註銷</a></li>
                    <li><a href="/#/">修改密碼</a></li>
{#                {% else %}#}
                    <li><a href="/#/">登陸</a></li>
                    <li><a href="/#/">註冊</a></li>
{#                {% endif %}#}
            </ul>
            <form class="navbar-form navbar-right">
                <input type="text" class="form-control" placeholder="搜索">
            </form>
        </div>
    </div>
</nav>
<div class="container">
        <div class="row col-md-3">
            <div class="panel panel-primary">
                <div class="panel-body">
                    網站分類
                </div>
                <div class="panel-footer">
                    {% for site in site_list %}
                        <div class="panel panel-primary">
                            <div class="panel-heading cate_title">{{site.name}}</div>
                            <div class="panel-body hides">
                                {% for sitearticlecategory in site.sitearticlecategory_set.all %}
                                    <p><a href="/site/{{sitearticlecategory.name}}">{{sitearticlecategory.name}}</a></p>
                                {% endfor %}
                            </div>
                        </div>
                    {% endfor %}
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <div class=" article_list">
                {% for article in article_list %}
                    <div><a href="">{{article.title}}</a></div>
                    <div class="row">
                        <div class="avatar col-md-2">
                            <a href="{% url 'aaa'  article.user.username %}"><img src="{{article.user.avatar.url}}" alt="" width="80px" height="80px"></a>
                        </div>
                        <div class="summary col-md-10" >
                            <p>{{article.summary}}</p>
                        </div>
                    </div>
                    <div class="article_info row">
                        &nbsp&nbsp<a href="/app01/{{ article.user.username }}"><b>{{article.user.username}}</b></a> &nbsp&nbsp發佈與:{{article.create_time|date:"Y-m-d H:i"}}
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-comment"></span>評論({{article.comment_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-thumbs-up"></span>點贊({{article.poll_count}})</a>
                        &nbsp&nbsp<a href=""><span class="glyphicon glyphicon-share-alt"></span>閱讀({{article.read_count}})</a>
                    </div>
                    <hr>
                {% endfor %}
            </div>
        </div>
        <div class="col-md-3">
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
            <div class="panel panel-default">
                <div class="panel-body">
                    Panel content
                </div>
                <div class="panel-footer">Panel footer</div>
            </div>
        </div>
    </div>
<script>
     $(".cate_title").mouseover(function () {
        $(this).next().slideDown(300)
    }).parent().mouseleave(function () {
         $(this).children(".panel-footer").slideUp(300)
     });
{#    $(".cate_title").mouseenter(function () {#}
{#        $(this).next().slideDown(300)#}
{#    });#}
{#    $(".panel-footer").mouseleave(function () {#}
{#        $(this).next().slideUp(300)#}
{#    });#}
</script>
</body>
</html>
View Code

四:我的博客主頁:  

頁面:

 

 

 前端代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>{{username}}博客首頁</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <link rel="stylesheet" href="/static/css/homeSite.css">
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="MenuBar">
        <div class="heeder">
            <div class="leftbutton">
                    <span class="abuttn">{{current_user.username}}</span>
                    <a href="" class="abuttn">博客園</a>
            </div>
            <div class="key-search">
                <form action="/" method="post">
                    <a href="#" class="i">
                        <span class="ico"></span>
                    </a>
                </form>
            </div>
            <div class="rightbutton">
                <a href="" class="abuttn">首頁</a>
                <a href="" class="abuttn">新隨筆</a>
                <a href="" class="abuttn">聯繫</a>
                <a href="" class="abuttn">訂閱</a>
                <a href="" class="abuttn">管理</a>
            </div>
        </div>
    </div>
    <div class="container homeSite">
        <div class="row">
            <div class="col-md-3 userinfo">
                <div class="well well-lg ">
                    <h4 class="col-lg-offset-3">我的信息</h4>
                    <p>---------------------------------------------</p>
                    <p><img src="{{current_user.avatar.url}}" alt="" width="100px" height="100px" class="img-circle"></p>
                    <p>暱稱:&nbsp&nbsp&nbsp&nbsp<span>{{current_user.username}}</span></p>
                    <p>園齡:</p>
                    <p>粉絲:</p>
                    <p>關注:</p>
                    <a href="">+關注</a>
                </div>
                <div class="panel panel-primary">
                    <div class="panel-heading"><b>分類歸檔</b></div>
                    <div class="panel-body">
                        {% for classfication in classfication_list %}
                            <p><a href="/app01/{{ current_user.username }}/classify/{{classfication.0}}">{{classfication.0}}({{classfication.1}})</a></p>
{#                            <p>{{ classfication }}</p>#}
                        {% endfor %}
                    </div>
                    <div class="panel-heading"><b>標籤歸檔</b></div>
                    <div class="panel-body">
                        {% for tag in tag_list %}
                            <p><a href="/app01/{{current_user.username}}/tag/{{tag.0}}">{{tag.0}}({{tag.1}})</a></p>
                        {% endfor %}


                    </div>
                    <div class="panel-heading"><b>日期歸檔</b></div>
                    <div class="panel-body">
                        {% for date in date_list %}
                            <p><a href="/app01/{{current_user.username}}/date/{{date.0}}">{{date.0}}({{date.1}})</a></p>
                        {% endfor %}
                    </div>
                </div>
            </div>
{#            文章#}
            <div class="col-md-9 articleinfo">
            {% block content %}
                {% for article in article_list %}
                        <div class="well well-lg ">
                            <div class="col-lg-offset-9">
                                <h4>{{article.create_time|date:"Y年m月d日"}}</h4>
                            </div>
                            <p>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------</p>
                            <h3><a href="/app01/{{current_user.username}}/article/{{article.id}}"><b>{{article.title}}</b></a></h3>
                            <hr>
                            <div class="summary">
                                <p>{{article.summary}}<span><a href="">閱讀全文</a></span></p>
                            </div>
                            <hr>
                            <div class="col-lg-offset-5 info">
                                發表於:<span>{{article.create_time|date:"Y-m-d  H:i"}}</span>
                                &nbsp&nbsp評論:<span>({{article.comment_count}})</span>
                                &nbsp&nbsp點贊:<span>({{article.poll_count}})</span>
                                &nbsp&nbsp閱讀:<span>({{article.read_count}})</span>
                                &nbsp&nbsp&nbsp&nbsp<span><a href="">編輯</a></span>
                            </div>
                        </div>
                    {% endfor %}
            {% endblock %}

            </div>
        </div>
    </div>
</body>
</html>
View Code

後端代碼:

#我的主頁
def homeSite(request,username,**kwargs):
    # print(kwargs)
    # print(username)
    """點擊文章用戶名或,頭像跳轉的此頁"""
    current_user = models.UserInfo.objects.filter(username=username).first()#獲取當前用戶
    # current_blog = current_user.blog#獲取當前博客
    if not current_user:
        return render(request,"notFound.html")
    current_blog = current_user.blog  # 獲取當前博客
    #查詢當前文章
    article_list=models.Article.objects.filter(user=current_user)
    #查詢 當前用戶的分類歸檔
    classfication_list=models.Classfication.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("title","c")
    #查詢當前用戶的標籤歸檔
    tag_list=models.Tag.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("name","c")
    #查詢當前用戶的標籤歸檔
    date_list = models.Article.objects.filter(user=current_user).extra(
        select={"filter_create_date": "strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(Count("id"))
    if kwargs:
        if kwargs.get("condition")=="classify":
            print(kwargs.get("condition"))
            article_list = models.Article.objects.filter(user=current_user,classify__title=kwargs.get("para"))
            # article_list = models.Article.objects.filter(user=current_user, category__title=kwargs.get("para"))
        elif kwargs.get("condition")=="tag":
            article_list = models.Article.objects.filter(user=current_user,tags__name=kwargs.get("para"))
        elif kwargs.get("condition")=="date":
            year,month=kwargs.get("para").aplit("/")
            article_list = models.Article.objects.filter(user=current_user,create_time__year=year,create_time__month=month)
    return render(request,"homeSite.html", locals())
View Code

url路由:

from django.conf.urls import include, url
from django.contrib import admin
from django.views.static import serve
from Blog_long import settings
from app01 import views
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^login', views.login),  #登陸
    url(r'^get_authCode_img/', views.get_authCode_img), #驗證碼
    url(r'^log_out',views.log_out),  #註銷
    url(r'^register', views.register),  # 註冊
    url(r'^index', views.index),#主頁
    # media 配置
    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
    #首頁點擊分類查詢到屬於這個類的文章
    url(r'^site/(?P<site_article_category>.*)/$', views.index),
    #我的站點首頁,路由分發
    url(r'^app01/', include('app01.urls')),

]
View Code

分發路由:

from django.conf.urls import include, url
from app01 import views
urlpatterns = [
    url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
    url(r'^(?P<username>.*)/article/(?P<article_id>\d+)', views.contentsArticle),
    url(r'^(?P<username>.*)',views.homeSite,name="aaa"),
]
View Code   

            1:點擊首頁中的--頭像--和--發佈人--,跳轉到所對應的我的我的博客首頁中。
            
                --頭像,發佈人都渲染在<a>標籤中。
                
                --路由分發:以...開頭,就映入到某個應用下的urls中進行匹配。
                
                    url(r'^app01/', include('app01.urls')),

url(r'^app01/', include('app01.urls')),

                   
                --給a標籤一個url,點擊走----url進行路由匹配,匹配成功走----所對應的視圖函數。
                

url(r'^(?P<username>.*)', views.homeSite,name="aaa"),

                    <a>標籤:----------點擊發布人-----發送一個url:以app01/開頭,引入到app01下的urls中,當前點擊的用戶名。進行路由匹配。
                                        "/app01/{{ article.user.username }}"
                                        0
                                ------點擊頭像-------經過別名,反向解析------找到別名是...的url,替換
                                ------視圖函數中也能夠用反向解析,原理相同,導入removes,傳參數要用args。
                                        {% url 'aaa'  article.user.username %}
                                        
                    urls:-------------有名分組,按關鍵字傳參,接收當前點擊的用戶名,返回到所對應的視圖函數中,加別名,用於反向解析。
                                        url(r'^(?P<username>.*)', views.homeSite,name="aaa"),
                    
                    視圖函數:--------接收kwargs鍵值對,和當前用戶名-----查詢當前用戶名是點擊的用戶名,的用戶信息對象,判斷用戶信息,若是不是返回錯誤信息。
                                    --返回我的博客頁面,返回用戶信息。
                    
                    查詢:------------經過我的用戶信息查詢到我的我的站點(我的博客)
                   

def homeSite(request,username,**kwargs):
    current_user = models.UserInfo.objects.filter(username=username).first()#獲取當前用戶
    current_blog = current_user.blog
    print(current_blog)#獲取當前博客
    if not current_user:
        return render(request,"notFound.html")
    #查詢當前文章
    article_list=models.Article.objects.filter(user=current_user)
    #查詢 當前用戶的分類歸檔
    classfication_list=models.Classfication.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("title","c")
    #查詢當前用戶的標籤歸檔
    tag_list=models.Tag.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("name","c")
    #查詢當前用戶的標籤歸檔
    date_list = models.Article.objects.filter(user=current_user).extra(
        select={"filter_create_date": "strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(
        Count("id"))
    if kwargs:
        if kwargs.get("condition")=="classify":
            article_list = models.Article.objects.filter(user=username,classify__title=kwargs.get("para"))
        elif kwargs.get("condition")=="tag":
            article_list = models.Article.objects.filter(user=username,tags__name=kwargs.get("para"))
        elif kwargs.get("condition")=="date":
            year,month=kwargs.get("para").aplit("/")
            article_list = models.Article.objects.filter(user=username,create_time__year=year,create_time__month=month)
    return render(request,"homeSite.html", locals())
View Code

            2:查詢當前用戶的文章對象-----找到文章表,過濾出user=當前用戶的文章,返回到頁面進行渲染。
            
            3:拿到用戶信息,---------返回到頁面渲染我的信息。
                
            4:分類歸檔
            
                1:-----查詢當前用戶,我的站點的分類對象-----分組查詢到(查詢當前用戶,我的站點的分類對象)的數目
                        classfication_list=models.Classfication.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("title","c")
                        
                2:-----返回到頁面進行渲染。
                        ----for循環分類對象,是一個元組,.0拿到分類,.1拿到分類數量。進行渲染。
                        
                3:-----點擊當前分類------查詢到當前分類的文章進行渲染。
                        ----<a>標籤-------當前分類渲染在a標籤中,點擊,發送一個url-----/app01/{{ current_user.username }}/classify/{{classfication.0}}----走urls。
                        ----urls:---------以app01開頭,有名分組(當前用戶),有名分組(歸檔方式),有名分組(具體分類)-----返回當前用戶名,鍵值對到---視圖函數----走視圖函數。
                            url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
                        ----視圖函數------拿到當前用戶名,鍵值對。
                            ----判斷kwargs中有名分組(分類)等不等於歸檔分類 ----if kwargs.get("condition")=="classify":----判斷正確進行查詢
                        ----查詢,-------查詢當前用戶我的站點所點擊分類的文章。-----返回到頁面進行渲染。
                            ----article_list = models.Article.objects.filter(user=username,classify__title=kwargs.get("para"))
            5:標籤歸檔-----點擊當前標籤------查詢到當前標籤的文章進行渲染。
                        ----<a>標籤-------當前分類渲染在a標籤中,點擊,發送一個url-----/app01/{{ current_user.username }}/tag/{{classfication.0}}----走urls。
                        ----urls:---------以app01開頭,有名分組(當前用戶),有名分組(歸檔方式),有名分組(具體標籤)-----返回當前用戶名,鍵值對到---視圖函數----走視圖函數。
                            url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
                        ----視圖函數------拿到當前用戶名,鍵值對。
                            ----判斷kwargs中有名分組(分類)等不等於歸檔標籤 ----if kwargs.get("condition")=="tag":----判斷正確進行查詢
                        ----查詢,-------查詢當前用戶我的站點所點擊標籤的文章。-----返回到頁面進行渲染。
                            ----article_list = models.Article.objects.filter(user=username,tags__name=kwargs.get("para"))
            
            6:日期歸檔-----點擊當前日期------查詢到當前日期的文章進行渲染。
                        ----<a>標籤-------當前分類渲染在a標籤中,點擊,發送一個url-----/app01/{{ current_user.username }}/data/{{classfication.0}}----走urls。
                        ----urls:---------以app01開頭,有名分組(當前用戶),有名分組(歸檔方式),有名分組(具體日期)-----返回當前用戶名,鍵值對到---視圖函數----走視圖函數。
                            url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
                        ----視圖函數------拿到當前用戶名,鍵值對。
                            ----判斷kwargs中有名分組(日期)等不等於歸檔分類 ----if kwargs.get("condition")=="data":----判斷正確進行查詢
                        ----查詢,-------查詢當前用戶我的站點所點擊標籤的文章。-----返回到頁面進行渲染。
                            ----獲取時間----year,month=kwargs.get("para").aplit("/")
                            ----article_list = models.Article.objects.filter(user=username,create_time__year=year,create_time__month=month)
            
 我的博客首頁:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>{{username}}博客首頁</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    <link rel="stylesheet" href="/static/css/homeSite.css">
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="MenuBar">
        <div class="heeder">
            <div class="leftbutton">
                    <span class="abuttn">{{current_user.username}}</span>
                    <a href="" class="abuttn">博客園</a>
            </div>
            <div class="key-search">
                <form action="/" method="post">
                    <a href="#" class="i">
                        <span class="ico"></span>
                    </a>
                </form>
            </div>
            <div class="rightbutton">
                <a href="" class="abuttn">首頁</a>
                <a href="" class="abuttn">新隨筆</a>
                <a href="" class="abuttn">聯繫</a>
                <a href="" class="abuttn">訂閱</a>
                <a href="" class="abuttn">管理</a>
            </div>
        </div>
    </div>
    <div class="container homeSite">
        <div class="row">
            <div class="col-md-3 userinfo">
                <div class="well well-lg ">
                    <h4 class="col-lg-offset-3">我的信息</h4>
                    <p>---------------------------------------------</p>
                    <p><img src="{{current_user.avatar.url}}" alt="" width="100px" height="100px" class="img-circle"></p>
                    <p>暱稱:&nbsp&nbsp&nbsp&nbsp<span>{{current_user.nickname}}</span></p>
                    <p>園齡:</p>
                    <p>粉絲:</p>
                    <p>關注:</p>
                    <a href="">+關注</a>
                </div>
                <div class="panel panel-primary">
                    <div class="panel-heading"><b>分類歸檔</b></div>
                    <div class="panel-body">
                        {% for classfication in classfication_list %}
                            <p><a href="/app01/{{ current_user.username }}/classify/{{classfication.0}}">{{classfication.0}}({{classfication.1}})</a></p>
{#                            <p>{{ classfication }}</p>#}
                        {% endfor %}
                    </div>
                    <div class="panel-heading"><b>標籤歸檔</b></div>
                    <div class="panel-body">
                        {% for tag in tag_list %}
                            <p><a href="/app01/{{current_user.username}}/tag/{{tag.0}}">{{tag.0}}({{tag.1}})</a></p>

                        {% endfor %}


                    </div>
                    <div class="panel-heading"><b>日期歸檔</b></div>
                    <div class="panel-body">
                        {% for date in date_list %}
                            <p><a href="/app01/{{current_user.username}}/date/{{date.0}}">{{date.0}}({{date.1}})</a></p>
                        {% endfor %}
                    </div>
                </div>
            </div>
{#            文章#}
            <div class="col-md-9 articleinfo">
                {% for article in article_list %}
                    <div class="well well-lg ">
                        <div class="col-lg-offset-9">
                            <h4>{{article.create_time|date:"Y年m月d日"}}</h4>
                        </div>
                        <p>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------</p>
                        <h3><a href=""><b>{{article.title}}</b></a></h3>
                        <hr>
                        <div class="summary">
                            <p>{{article.summary}}<span><a href="">閱讀全文</a></span></p>
                        </div>
                        <hr>
                        <div class="col-lg-offset-5 info">
                            發表於:<span>{{article.create_time|date:"Y-m-d  H:i"}}</span>
                            &nbsp&nbsp評論:<span>({{article.comment_count}})</span>
                            &nbsp&nbsp點贊:<span>({{article.poll_count}})</span>
                            &nbsp&nbsp閱讀:<span>({{article.read_count}})</span>
                            &nbsp&nbsp&nbsp&nbsp<span><a href="">編輯</a></span>
                        </div>
                    </div>
                {% endfor %}
            </div>
        </div>
    </div>
</body>
</html>
View Code

博客首頁-----和-----我的博客首頁--流程:

1:在url中寫主頁路由
                url(r'^index', views.index)
                
            2:建立視圖函數,從數據庫取出數據,返回到前端。
            
                -------找到文章表,取出文章對象,返回。
                
                -------找到網站分類表,取出分類對象,返回。
                
            3:返回到主頁html進行渲染:
            
                1:-----拿到文章對象用for標籤循環,{{.文章內容}}進行渲染。
                
                2:-----拿到分類對象用for標籤循環,{{.網站分類,父}}進行渲染。
                
                3:-----拿到網站分類對象,{{.(反向查詢,表名_set).網站分類,子}}進行渲染。
                
            4:JQ作動態摺疊效果,鼠標懸浮展開,鼠標移開摺疊。
            
                1:-----選擇器找到網站分類,給他綁定一個(懸浮)事件,當觸發這個事件(鼠標懸浮),執行function,$(this)找到選擇器對象,執行展開事件。
                
                2:-----選擇器找到網站分類的父級,給他綁定一個(懸浮)執行function,$(this)找到選擇器對象,執行摺疊事件事件。        
                         $(".cate_title").mouseover(function () {
                            $(this).next().slideDown(300)
                        }).parent().mouseleave(function () {
                             $(this).children(".panel-footer").slideUp(300)
                         });
                         
            5:點擊網站分類,子分類,查找到這個分類下的全部文章。
            
                -------分類渲染在<a>標籤中,給他一個url,鼠標點擊,------走urls進行路由匹配--------找url的視圖函數--------進行查找
                
                        a標籤:---------/site/{{網站分類,name}}
                        
                        url:------------以site開頭,有名分組(接收點擊的分類),按關鍵字傳參.*匹配全部,返回一個鍵值對,返回到視圖函數。 
                                        url(r'^site/(?P<site_article_category>.*)/$', views.index),
                                        
                        視圖函數--------**kwargs接收鍵值對,判斷kwargs,判斷正確,進行網站查詢,不然查詢全部文章。
                        
                        查詢------------找到文章表,過濾(反向查詢按字段)出文章的網站分類,子分類 =kwargs傳過來的分類,返回到前端進行渲染。
                                    article_list = models.Article.objects.filter(site_article_category__name=kwargs.get("site_article_category"))
                                    
    四:我的博客主頁:
    
            1:點擊首頁中的--頭像--和--發佈人--,跳轉到所對應的我的我的博客首頁中。
            
                --頭像,發佈人都渲染在<a>標籤中。
                
                --路由分發:以...開頭,就映入到某個應用下的urls中進行匹配。
                
                    url(r'^app01/', include('app01.urls')),
                    
                --給a標籤一個url,點擊走----url進行路由匹配,匹配成功走----所對應的視圖函數。
                
                    <a>標籤:----------點擊發布人-----發送一個url:以app01/開頭,引入到app01下的urls中,當前點擊的用戶名。進行路由匹配。
                                        "/app01/{{ article.user.username }}"
                                        0
                                ------點擊頭像-------經過別名,反向解析------找到別名是...的url,替換
                                ------視圖函數中也能夠用反向解析,原理相同,導入removes,傳參數要用args。
                                        {% url 'aaa'  article.user.username %}
                                        
                    urls:-------------有名分組,按關鍵字傳參,接收當前點擊的用戶名,返回到所對應的視圖函數中,加別名,用於反向解析。
                                        url(r'^(?P<username>.*)', views.homeSite,name="aaa"),
                    
                    視圖函數:--------接收kwargs鍵值對,和當前用戶名-----查詢當前用戶名是點擊的用戶名,的用戶信息對象,判斷用戶信息,若是不是返回錯誤信息。
                                    --返回我的博客頁面,返回用戶信息。
                    
                    查詢:------------經過我的用戶信息查詢到我的我的站點(我的博客)
                    
            2:查詢當前用戶的文章對象-----找到文章表,過濾出user=當前用戶的文章,返回到頁面進行渲染。
            
            3:拿到用戶信息,---------返回到頁面渲染我的信息。
                
            4:分類歸檔
            
                1:-----查詢當前用戶,我的站點的分類對象-----分組查詢到(查詢當前用戶,我的站點的分類對象)的數目
                        classfication_list=models.Classfication.objects.all().filter(blog=current_blog).annotate(c=Count("article__id")).values_list("title","c")
                        
                2:-----返回到頁面進行渲染。
                        ----for循環分類對象,是一個元組,.0拿到分類,.1拿到分類數量。進行渲染。
                        
                3:-----點擊當前分類------查詢到當前分類的文章進行渲染。
                        ----<a>標籤-------當前分類渲染在a標籤中,點擊,發送一個url-----/app01/{{ current_user.username }}/classify/{{classfication.0}}----走urls。
                        ----urls:---------以app01開頭,有名分組(當前用戶),有名分組(歸檔方式),有名分組(具體分類)-----返回當前用戶名,鍵值對到---視圖函數----走視圖函數。
                            url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
                        ----視圖函數------拿到當前用戶名,鍵值對。
                            ----判斷kwargs中有名分組(分類)等不等於歸檔分類 ----if kwargs.get("condition")=="classify":----判斷正確進行查詢
                        ----查詢,-------查詢當前用戶我的站點所點擊分類的文章。-----返回到頁面進行渲染。
                            ----article_list = models.Article.objects.filter(user=username,classify__title=kwargs.get("para"))
            5:標籤歸檔-----點擊當前標籤------查詢到當前標籤的文章進行渲染。
                        ----<a>標籤-------當前分類渲染在a標籤中,點擊,發送一個url-----/app01/{{ current_user.username }}/tag/{{classfication.0}}----走urls。
                        ----urls:---------以app01開頭,有名分組(當前用戶),有名分組(歸檔方式),有名分組(具體標籤)-----返回當前用戶名,鍵值對到---視圖函數----走視圖函數。
                            url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
                        ----視圖函數------拿到當前用戶名,鍵值對。
                            ----判斷kwargs中有名分組(分類)等不等於歸檔標籤 ----if kwargs.get("condition")=="tag":----判斷正確進行查詢
                        ----查詢,-------查詢當前用戶我的站點所點擊標籤的文章。-----返回到頁面進行渲染。
                            ----article_list = models.Article.objects.filter(user=username,tags__name=kwargs.get("para"))
            
            6:日期歸檔-----點擊當前日期------查詢到當前日期的文章進行渲染。
                        ----<a>標籤-------當前分類渲染在a標籤中,點擊,發送一個url-----/app01/{{ current_user.username }}/data/{{classfication.0}}----走urls。
                        ----urls:---------以app01開頭,有名分組(當前用戶),有名分組(歸檔方式),有名分組(具體日期)-----返回當前用戶名,鍵值對到---視圖函數----走視圖函數。
                            url(r'^(?P<username>.*)/(?P<condition>classify|tag|date)/(?P<para>.*)', views.homeSite),
                        ----視圖函數------拿到當前用戶名,鍵值對。
                            ----判斷kwargs中有名分組(日期)等不等於歸檔分類 ----if kwargs.get("condition")=="data":----判斷正確進行查詢
                        ----查詢,-------查詢當前用戶我的站點所點擊標籤的文章。-----返回到頁面進行渲染。
                            ----獲取時間----year,month=kwargs.get("para").aplit("/")
                            ----article_list = models.Article.objects.filter(user=username,create_time__year=year,create_time__month=month)
View Code

 五:文章詳細(重點:點贊,評論)

   解決bug:登陸點贊,不登陸返回登陸頁面。

六:後臺管理

   1:後臺頁面設計:-----------------給(管理)a標籤一個路由:/app01/manage/

 

    url:

url(r'^manage/$',views.manage),

  前端代碼:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale">
    <title>後臺管理</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <script src="/static/kindeditor/kindeditor-all-min.js"></script>
</head>
<body>
<div class="" style="background-color: #2459a2;height: 50px;width: 100%">
    <div class="container">
        <a class="navbar-brand" href="#"><b>{{ user.username }}博客園後臺管理</b></a>
        <div id="bs-example-navbar-collapse-9" class="collapse navbar-collapse">
            <ul class="nav navbar-nav navbar-right">
                <li><a href="/logout/">註銷</a></li>
                <li><a href="/setpassword/">修改密碼</a></li>
            </ul>
        </div>
    </div>
</div>
<p></p>
<div class="row col-md-2">
    <div class="panel panel-primary ">
        <div class="panel-heading"><b>操做</b></div>
        <div class="panel-body">
            <div class="panel-footer"><a href="/app01/manage/"><< 文章管理 >></a></div>
            <div class="panel-footer"><a href=""><< 分類管理 >></a></div>
            <div class="panel-footer"><a href=""><< 標籤管理 >></a></div>
            <div class="panel-footer"><h2>{{ user }}!</h2></div>
        </div>
    </div>
</div>
<div class="col-md-9 sidebar alert-warning col-lg-offset-1">
    {% block manage %}
        <div class="bs-example" data-example-id="contextual-table">
            <table class="table">
                <thead>
                <tr>
                    <th>標題</th>
                    <th>評論數</th>
                    <th>點贊數</th>
                    <th>操做</th>
                    <th>操做</th>
                    <th><a href="/app01/manage/add_article/">
                        <button class="btn btn-primary">添加</button>
                    </a></th>
                </tr>
                </thead>
                <tbody>
                {% for article in article_list %}
                    <tr>
                        <td>{{ article.title }}</td>
                        <td>{{ article.comment_count }}</td>
                        <td>{{ article.poll_count }}</td>
                        <td><a href="">
                            <button class="btn btn-primary">編輯</button>
                        </a></td>
                        <td><a href="">
                            <button class="btn btn-danger">刪除</button>
                        </a></td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    {% endblock %}
</div>
</body>
</html>
View Code

  後端代碼:

def manage(request):
    if not request.user.is_authenticated():
        return redirect("/login/")
    article_list = models.Article.objects.filter(user=request.user).all()
    print(article_list)
    return render(request,"manage.html",{"article_list":article_list})
View Code

  2:文章管理:

     ----添加文章:

 

           url:

url(r'^manage/add_article/$',views.add_article),

           前端代碼:

{% extends "manage.html"%}
{% block manage %}
    {% csrf_token %}
    <h4>添加文章:</h4>
    <form action="/app01/manage/add_article/" method="post" novalidate>
    {% csrf_token %}
        <div>
            <label for="title">標題:</label>
            <p>{{ article_form.title }} {{ article_form.errors.title.0 }}</p>
        </div>
        <div>
            <label for="content">內容:</label>
            <p>{{ article_form.content }} {{ article_form.errors.content.0 }}</p>
        </div>
        <p><button class="btn-sm btn-primary">提交</button></p>
    </form>
     <script>
            KindEditor.ready(function (K) {
                window.editor = K.create('#id_content', {
{#                    寬#}
                    width: "1100px",
{#                    高#}
                    height: "450px",
{#                    是否能夠拖動#}
                    resizeType: 0,
{#                    指定上傳文件的終端,對應在url,視圖函數#}
                    uploadJson: "/uploadFile/",

                    extraFileUploadParams: {
                        csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
                    }
                });
            })
     </script>
{% endblock %}
View Code

          添加文章Form組件:

#文章From組件
class ArticleFrom(forms.Form):
    title = forms.CharField(
        required=True,
        max_length=20,
        error_messages={
            "required":"不能爲空",
        },widget=widgets.TextInput(attrs={ 'class': 'form-control'}))
    content = forms.CharField(
        required=True,
        error_messages={
            "required": "不能爲空",
    },widget=widgets.Textarea(attrs={ 'class': 'form-control'}))
    def clean_content(self):
        # 拿到文章內容
        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")
View Code

          後端代碼:

def add_article(request):
    if request.method=="POST":
        article_form = ArticleFrom(request.POST)
        if article_form.is_valid():
            title = article_form.cleaned_data.get("title")
            content = article_form.cleaned_data.get("content")
            article_obj = models.Article.objects.create(title=title,summary=content[0:30],create_time=datetime.datetime.now(),user=request.user)
            models.Article_detail.objects.create(content=content,article=article_obj)
            return HttpResponse("添加成功")
        else:
            pass
    article_form=ArticleFrom
    return render(request,"add_article.html",{"article_form":article_form})
View Code

 

  3:添加kindeditor編輯器

    下載:http://kindeditor.net/docs/option.html

編輯器(kindeditor)--------------------------------------http://kindeditor.net/docs/option.html 

     導入

    

    引用:

 

    綁定編輯器:

    

    代碼:

View Code

    url:

#編輯器上傳文件
    url(r'^uploadFile/$', views.uploadFile),

     視圖函數:-----------------文件預覽

    

  

    

 

View Code

    4:XSS攻擊----用(beautifulsoup4模塊實現)

    (beautifulsoup4)----------------------------------------http://www.cnblogs.com/yuanchenqi/articles/7617280.html

       ----下載:

        

      ----xss組件:

        

        代碼:

from bs4 import BeautifulSoup
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"]}
    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()
View Code

      -----from組件 過濾,鉤子

        代碼:

from django import forms
from django.forms import fields
from django.forms import widgets,ValidationError
from app01 import models
from app01.plugins import xss_plugin
from django.core.validators import RegexValidator
#註冊Form組件
class RegisterForm(forms.Form):
    """註冊Form組件"""
    username = forms.CharField(
        required=True,
        min_length=3,
        max_length=8,
        error_messages={
            'required': '用戶不能爲空',
            'min_length': '用戶長度不能小於3',
            'max_length': '用戶長度不能大於8',
        },widget=widgets.TextInput(attrs={'placeholder': '用戶名:', 'class': 'form-control'}))
    password = fields.CharField(
        required=True,
        min_length=3,
        max_length=8,
        error_messages={
            'required': '密碼不能爲空',
            'min_length': '密碼長度不能小於3',
            'max_length': '密碼長度不能大於8',
            # 'invalid': '密碼格式錯誤',
        },
        # validators=[RegexValidator('\d+', '只能是數字')],
        widget=widgets.PasswordInput(attrs={'placeholder': '密碼:', 'class': 'form-control'}))
    confirm_password = fields.CharField(
        required=True,
        min_length=3,
        max_length=8,
        error_messages={
            'required': '確認密碼不能爲空',
            'min_length': '確認密碼長度不能小於3',
            'max_length': '確認密碼長度不能大於8',
        },
        widget=widgets.PasswordInput(attrs={'placeholder': '確認密碼:', 'class': 'form-control'}))

    email = fields.EmailField(
        required=True,
        error_messages={
            'required':'郵箱不能爲空',
            'invalid':'郵箱格式錯誤'},
        widget=widgets.EmailInput(attrs={'placeholder':'郵箱:','class':'form-control'}))


    def clean_username(self):
        """用戶名"""
        ret = models.UserInfo.objects.filter(username=self.cleaned_data.get("username"))
        if not ret:
            return self.cleaned_data.get("username")
        else:
            raise ValidationError("用戶名已註冊")

    def clean_password(self):
        """密碼"""
        data = self.cleaned_data.get("password")
        if not data.isdigit():
            return self.cleaned_data.get("password")
        else:
            raise ValidationError("密碼不能全是數字")

    # def clean_auth_code(self):
    #     if self.cleaned_data.get("auth_code")==self.request.session.get("auth_code"):
    #         return self.cleaned_data.get("auth_code")
    #     else:
    #         raise ValidationError("驗證碼錯誤")

    def clean(self):
        if self.cleaned_data.get("password")==self.cleaned_data.get("confirm_password"):
             return self.cleaned_data
        else:
            raise ValidationError("兩次密碼不一致")

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request=request
#文章From組件
class ArticleFrom(forms.Form):
    title = forms.CharField(
        required=True,
        max_length=20,
        error_messages={
            "required":"不能爲空",
        },widget=widgets.TextInput(attrs={ 'class': 'form-control'}))
    content = forms.CharField(
        required=True,
        error_messages={
            "required": "不能爲空",
    },widget=widgets.Textarea(attrs={ 'class': 'form-control'}))
    def clean_content(self):
        # 拿到文章內容
        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")
View Code
相關文章
相關標籤/搜索