博客應用項目之,系統主頁及個人主頁


1、cookie和session
  cookie可以單獨工作
  cookie也可以和session配合來用
  每一個瀏覽器都會有一個cookie:{}
  瀏覽器第一次訪問服務器的時候cookie是空的
  服務器需要讓客戶端保存一些數據cookie {"sessionID":"隨機字符串"},當下次請求的時候就會帶着一些你保存的數據
  django_session表里的每一條記錄就是一個個用戶,類似一個大的字典
  session_key:存的是sessionID對應的值
  session_data:{"":"","":"",...}存的是一組組鍵值對
  等再次訪問的時候就會帶着sessionID


2、登錄和注冊
  - 登錄(ajax)
    - 涉及驗證碼的實現(可以吧獲取的驗證碼存放在session中,以方便驗證的時候判斷。每次訪問的時候瀏覽器都會帶着你存放在里面的值,用的時候取它就行了)
    - 登錄成功之后設置session,以后每次請求進來的時候瀏覽器都會帶着cookie,就知道是誰進來了。保存了狀態。(用auth模塊)

user=auth.authenticate(username=username,password=password)#驗證用戶名和密碼
if user:
ret["flag"] = True
auth.login(request,user) #session request.session["flag"]=True    #如果認證成功,就讓登錄,這個login里面包括了session操作和cookie
...

    如果是當前的用戶就做什么操作,如果不是當前的用戶就不讓他進
  - 注冊(ajax+Form)
    - 涉及頭像的實現
    具體見上篇博客
3、系統主頁
1、設計系統主頁(系統主頁是用戶不管登錄不登錄都是可以看到的,所以沒必要進行驗證)
  - 導航條:
    - 需要注意的是:
    - 如果用戶是登錄進來的,就讓顯示登錄狀態;如果用戶還沒有登錄,就在導航條上顯示登錄,注冊(如圖)

登錄狀態

沒有登錄狀態

   所以具體我們還得判斷一下

 {% if request.user.is_authenticated %}
         <li class="active"><a href="#"><span
               class="glyphicon glyphicon-user"></span>{{ request.user.username }}</a></li>
         <li class="active"><a href="/log_out/">注銷</a></li>
  {% else %}
         <li class="active"><a href="/login/">登錄</a></li>
         <li class="active"><a href="/register/">注冊</a></li>
  {% endif %}

  - 注銷
  - 修改密碼
  像是注銷,登錄,修改密碼我們都可以借助auth模塊來實現

  - 具體顯示內容可以分三大塊
    - 左側菜單系列
    - 顯示文章系列
      - 文章標題:
      - 作者頭像:
      - 是誰發布的,發布時間,等...
      - 文章不可能只有一篇,會有好多篇文章,這是還得加上分頁
    - 右側可以放一寫其他信息

2、下面是具體流程,需要注意的知識點
    ====================================
    當做左側的時候需要多加兩張表
      - 多加了一個網站分類表和網站文章分類表(可參考博客園cnblogs.com的系統主頁)
      - 一個網站分類里面又可以對文章分好多類 (建立了一對多的關系)
      - 文章分類里面又有好多相關的具體文章(建立了一對多的關系) 注意關聯字段要寫在多的一方

class SiteCategory(models.Model):
    '''網站分類表'''
    name = models.CharField(max_length=32,verbose_name="分類名")
    class Meta:
        verbose_name_plural="網站分類表"
    def __str__(self):
        return self.name

class SiteArticleCategory(models.Model):
    '''網站文章分類表'''
    name = models.CharField(max_length=32,verbose_name="分類名")
    sitecategory = models.ForeignKey(to="SiteCategory",verbose_name="所屬網站")

    class Meta:
        verbose_name_plural = "網站文章分類表"
    def __str__(self):
        return self.name

 

    ====================================
    - 建立好關系之后就可以實現左側菜單了
      - 左側菜單需要注意的是你點擊菜單的時候的跳轉路徑,當然有人會想到用模板繼承的方式,這種方式是能實現,但是還有一種更機智的辦法。我們可以參考博客園的跳轉路徑,還是繼續走index視圖,
      但是我們得把路徑匹配一下,如圖

url(r'^index/', views.index),
url(r'^$', views.index), #根目錄下也讓走index
url(r'^cate/(?P<site_article_category>.*)/', views.index) #有名分組

 


注意:
  【1】
    這時得注意,你的index現在有兩個路徑了,所以我們不能直接把site_article_category傳進去, 我們得用一個**kwargs來接受(因為你的url(r'^login/$', views.login)這個路徑是沒有參數的,
    如果你直接吧site_article_category這樣傳進去,就會報錯了,區分不了要走有路徑的還是要走沒有路徑的,所以我們用**kwargs),當有參數的時候,有名分組是按照關鍵字傳參數的,所以會把傳進來的值                 以字典的形式讓kwargs接收;當沒有參數的時候。就走index/路徑,直接顯示index首頁就行了
  【2】
    當兩個路徑有沖突的時候,一定要把規則少的放在匹配多的上面,不然就會給覆蓋了
  【3】
    在模板中渲染的時候,需要在后端先把數據查出來,然后在前端渲染
    ====================================
    - 顯示文章系列
    - 查出所有的文章,渲染在頁面(以及標題啊什么的,只要有article對象了,渲染的時候在頁面中用.的方式,就可以查到信息了)
    需要注意的是:這里需要判斷一下。具體如下

print("-----------",kwargs) #接收到的是一個字典
kwargs = kwargs.get("site_article_category")
print("=======",kwargs) #得到的是site_article_category對應的值
if kwargs:
  print("xxxxxxxxxxxxxx")
  article_obj = models.Article.objects.filter(site_article_category__name=kwargs) # article_obj打印的是一個對象 ,如果點擊的是左側的,就讓現實左側的相關文章
else:
  article_obj = models.Article.objects.all()#如果沒有點擊左側就查詢所有的文章

  - 點擊頭像跳轉

<div class="avatar col-md-2">
<a href="{% url 'aaa' article.user.username %}"> <!-- 跳轉路徑--> 這里是用到了
<img src="{{ article.user.avatar.url }}" alt="" width="60" height="60"></a><!-- 圖片路徑-->
</div>

注意:
  【1】:跳轉路徑

<a href="{% url 'aaa' article.user.username %}"> <!-- 跳轉路徑--> 這里是用到了反向解析(按照別名去匹配路徑),因為url現在是有參數的,所以后面還得加上參數 
url(r'^(?P<username>.*)/$', views.homesite, name='aaa'), 

  【2】:圖片路徑有兩種方式:

1、我們也可以指定/media/{{article.user.avatar}}
2、直接{{article.user.avatar.url}} django會自動找到圖片對應的位置

  - 分頁

{% if article_obj.has_previous %}
<li class="previous"><a href="{{ request.path_info }}?page={{ article_obj.previous_page_number }}">上一頁</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一頁</a></li>
{% endif %}

注意:
  【1】:一定要把跳轉路徑對應好了,不然就混亂了。

4、個人主頁
設計個人主頁的時候,可以仿照博客園的頁面設計,當然每個人的個人主頁都是不一樣的,不過這個也挺簡單的,下面會說到
我設計的個人主頁:還是分了三大塊
  - 導航條:
  - 左側:
    - 個人信息
    - 我的標簽
    - 隨筆分類
    - 日期歸檔
  - 右側:顯示文章
  - 涉及到的知識點
  1、模板繼承
    當點擊文章標題的時候用到,因為當點擊文章標題的時候,就要顯示具體的文章內容
    這時候需要再走一個路由,專門處理具體的文章內容的操作

 標題#}
<div class="title">
  <h4><a href="/blog/{{ current_user.username }}/articles/{{ article.id }}">{{ article.title }}</a></h4>
</div>

  url:這里用到的是路由分發。。。

 url(r'^(?P<username>.*)/articles/(?P<article_id>\d+)/$', views.article_detail),

  注意:在admin錄入文章內容數據的時候,如果你直接吧隨便找的文章粘貼過來,這樣粘貼過來的是沒有樣式的,我們要把html源碼粘貼進去
       當吧源碼粘貼進去的時候會全部都是標簽,而不是文章內容,這是由於做了安全機制了,吧標簽當成是字符串了,我們得告訴瀏覽器。
     我的代碼是安全的,這樣才會顯示中文。
  解決辦法:safe <p>{{ article_obj.article_detail.content|safe }}</p>
  2、ORM查詢
    1、查詢操作

# 查詢當前用戶下的所有文章
current_user = models.UserInfo.objects.filter(username=username).first()
models.Article.objects.filter(user=current_user)
#查看當前用戶的個人博客,(個人博客和用戶是一對一的關系,一個用戶有一個個人博客)
current_user.blog
#查詢當前用戶下的而所有的分類以及文章數
models.Classfication.objects.filter(blog=current_blog).annotate(count=Count("article__title")).values_list("title","count")
#查詢當前用戶下的而所有的標簽以及文章數
models.Tag.objects.all().filter(blog=current_blog).annotate(count=Count("article__id")).values_list("name","count")
#查詢當前用戶下的而所有的年月日期以及文章數
models.Article.objects.all().filter(user=current_user).extra(select={"filter_create_date":"strftime('%%Y/%%m',create_time)"}).values_list("filter_create_date").annotate(Count("title"))

涉及:
  基於對象查詢

  基於雙下划線,分組函數 annotate

理解分組:

  查日期的時候:extra過濾

  3、左側的標簽分類和隨筆分類,日期歸檔,當點擊的時候跳轉,參照博客園的跳轉路徑,具體操作和系統主頁的類似,不需要模板繼承,也不需要跳轉到其他的地方,讓還在當前頁面上跳轉
  我們可以吧跳轉路徑匹配一下
  url(r'^(?P<username>.*)/(?P<condition>category|tag|data)/(?P<para>.*)/$', views.homesite),

  在HTML中:

日期歸檔,
<p><a href="/blog/{{ current_user.username }}/data/{{ data.0 }}/">{{ data.0 }}({{ data.1 }})</a></p>
隨筆分類
<p><a href="/blog/{{ current_user.username }}/category/{{ category.0 }}/">{{ category.0 }}({{ category.1 }})</a></p>
標簽分類
<p><a href="/blog/{{ current_user.username }}/tag/{{ tag.0 }}/">{{ tag.0 }}({{ tag.1 }})</a></p>

  4、每個人都有一套默認的皮膚
    1、在static下創建一個存皮膚的文件夾user_home_style
      a.css 設置a樣式
      b.css 設置b樣式
      ....
    2、吧homesite里面的你不想用的樣式刪除了
    3、在數據庫里吧theme主題修改一下,存成  a.css
                        b.css
                        ....
    4、導入:在link的時候{{current_user.blog.theme}}

<link rel="stylesheet" href="/static/user_home_style/{{ current_user.blog.theme }}"> #這樣就每個用戶對應的樣式就找到了

5、個人主頁的文章詳細以及點贊和評論

  涉及到的知識點:
    - ajax
    - F查詢

  點贊思路:用ajax實現:
    發送數據,要對那篇文章點贊,需要發一個article_id
    還需要知道當前用戶的id,這個我們可以不用ajax發了,直接在后端查出來,用request.user.nid
    在后端接收數據
      先創建贊示例
      models.Article_poll.objects.create(user_id=user_id,article_id=article_id)
      然后點贊數+1
      models.Article.objects.filter(id=article_id).update(poll_count=F("poll_count")+1)
    然后返回給前端,在前端渲染
    渲染的時候
      1、吧頁面上的數字加1,並且顯示點贊成功
      2、如果已經點過贊了,提示不能重復點贊,
      3、如果是用戶登錄了可以點贊,沒有登錄提示請先登錄,登錄做個超鏈接,鏈接到login頁面
6、url:路徑斜杠問題
  當加/的時候,是從根目錄拼接
  當沒有加/的時候,是從當前路徑拼接
7、 查看當前用戶

current_user = models.UserInfo.objects.filter(username=username).first()
print("current_user==========",current_user,type(current_user)) 
print("request.user.username======",request.user.username,type(request.user.username))
打印結果 
current_user========== haiyan <class 'app01.models.UserInfo'> #對象
request.user.username====== haiyan <class 'str'> #字符串,,可以在頁面中渲染

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM