做一個官網需要多長時間

作者:小土豆
部落格園:www.cnblogs.com/HouJiao/
掘金://juejin.cn/user/2436173500265335

1. 前言

最近在做一個官網,主頁菜單欄有六項,對應六個大的模組,每個模組的展示形式大致如下:

1.1 純圖片展示

一張主圖橫向鋪滿瀏覽器:

图片.png

1.2 表格展示

图片.png

1.3 圖片+文字左右兩列布局展示

第一種左右兩列布局:

图片.png

第二種左右兩列布局:

图片.png

1.4 圖片+文字上下兩行布局展示

图片.png

1.5 12宮格三行四列的圖片展示

图片.png

1.6 瀑布流式的圖片展示

图片.png

1.7 動態效果

除了上面的那些布局之外,還有一些滑鼠懸浮的動態效果。

1.8 新聞資訊模組

另外還有一個新聞資訊模組,可以查看新聞詳情以及帶分頁功能的新聞列表。雖然沒有詳細討論這個模組的具體內容,但是大概知道這個模組可能還需要一個簡單的後台管理系統去發布、編輯文章。

2. 到底花了多長時間

當時看完設計稿就覺得這個官網的內容還是有點多的,因為很多布局都不太一樣,而且還需要一個後台管理系統;最終經過一番思考,定下了3周的工作量(不包含周末)。

最終大體做完花了兩周的時間,因為前期缺乏溝通出現UI返工問題,後面還完善了一些功能,所以又花了一周時間,整體也算按時交付。

那接下就這個項目中的一些樣式、功能的實現以及整個過程中出現的一些問題總結出來,希望能給大家一些參考。

3. 本文適合那些人閱讀

  • 想學習CSS技能,但不知道從何下手的
  • 想簡單複習一下CSS技能
  • 最近有意願做官網項目的
  • 純前端開發,有意向入門後端,希望能獨立做一套完整但是又不複雜的前後端項目

4. 頁面布局和一些CSS效果

做官網這種項目,主要考驗一個人的CSS功底,那在這個項目完成的過程中都用到了那些CSS技巧呢?

  • 定位:相對定位、絕對定位
  • 彈性布局:Flex布局
  • 百分比布局
  • 文本溢出: 單行文本溢出、多行文本溢出
  • 滑鼠懸浮顯示遮罩:利用display和絕對定位

以上就是整個項目中用到的一些CSS技巧,接下來我們就來複習一下這些內容和一些相關的實踐應用。

4.1 相對定位

元素設置相對定位以後仍然在文檔流中佔據著自己原來的位置,通過設置top、bottom、left、right,可以使元素相對於原來的位置進行移動,相對定位不會影響其他元素的布局。

图片.png

4.1.1 相對定位-應用1

在項目中,有下面這樣的例子就是利用相對定位實現的。

图片.png

我們基礎的布局是下面這樣的:

<p class="logo">公司<br/>logo</p>  <!--這裡實際是img元素 -->
<p class="name">公司<br/>X<br/>名稱</p>

p.logo後期直接替換成img元素即可

正常情況下,上面的程式碼瀏覽器渲染結果如下(尺寸需要通過CSS設置):

图片.png

此時我們可以通過給p.name設置相對定位,並且設置其偏移量就可以實現最終的效果。

p.name{
    position: relative;
    left: 100px;
}

4.1.2 相對定位-應用2

图片.png

table中有一列數據為名稱,我們需要在數據前面加上對應的logo。

其實正常情況下,不對logo添加任何樣式,顯示出來是下面這樣的效果:

图片.png

很明顯的能看出來logo的位置並不是很合適:logo應該垂直居中,同時增加和文字的間距。

增加logo和文字之間的間距可以通過給logo設置padding-right或者margin-right來實現。

調整logo垂直居中一般會選擇vertical-align,但是我們經常會發現vertical-algin的效果總是不盡人意,那這個時候相對定位就是非常好的選擇。我們可以對logo設置相對定位,然後設置top將logo向下偏移。

.logo{
    positive: relative;
    top: 4px;
}

4.2 絕對定位

元素設置絕對定位以後,就會脫離正常文檔流,原先在文檔流中佔據的位置會被刪除,所以會影響它後面的元素。

图片.png

為絕對定位的元素設置偏移量後,絕對定位的元素的位置是相對於最近的已定位祖先元素,如果元素沒有已定位的祖先元素,那麼它的位置相對於最初的包含塊html元素。

已定位指的是設置了position:relative;或者position:absolute;。其中塊級元素設置絕對定位以後其內容將不再默認佔滿瀏覽器一整行,它的寬將由內容撐開。

在後面的內容中會有關於絕對定位的具體應用。

4.3 彈性布局

Flex布局也被稱為是彈性布局,通過給元素設置display:flex來實現。

Webkit內核的瀏覽器,必須加上-webkit前綴,即display: -webkit-flex;

如果元素設置了display:flex,那麼該元素就被稱為Flex容器,該元素內的子元素就被稱為Flex項目。

我們都知道,div是塊級元素。

<div class="wrapper">
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
</div>

所以上面這段程式碼在瀏覽器的布局如下:

图片.png

如果我們給div.wrapper設置display:flex;則div.wrapper就是一個Flex容器,它的子元素div.box都是Flex項目,而對應的布局會變成下面這樣:

图片.png

即Flex容器內部的Flex項目都會成為行內元素,水平依次排列且默認左對齊。

我們可以通過設置Flex容器的justify-content控制Flex項目的水平對齊方式。

图片.png

有關更多Flex布局的內容可以點擊這裡

那接下來我們看看項目中的Flex布局應用。

4.3.1 彈性布局應用

項目中應用到了Flex布局的就是下面這個模組:

图片.png

該模組由六張不同尺寸的圖片組成,並且六張圖片拼接成了一張完整的大圖。

剛開始看到這個設計的時候也沒多想,後面真正做的時候才開始摳腳o(╥﹏╥)o。網上搜索了一下,這種布局大致可以稱之為瀑布流式的布局。

大概看了網上的一些方法,總覺得看的不是很明白(實際是因為一直持續在做頁面布局,大腦有些反應不過來),於是自己就在琢磨怎樣先把目前的這個需求給實現了。

於是腦子各種發散,剛開始嘗試了浮動+相對定位,確實也實現了基本的布局。但是因為浮動導致父元素失去高度,後續有一個滑鼠懸浮的特性無法實現,經過一些折騰沒能解決就放棄了這種辦法。

出現的問題為:浮動導致父元素高度塌陷,感興趣的可以去了解一下~

之後經過一番諮詢,得到了一個非常簡單而支援自適應的方案,那就是Flex布局。那接下來就來掰掰我這個例子是怎麼用Flex布局實現的。

我們整體的布局是下面這樣的:

图片.png

首先我們將整個布局規整為三個div.box,並且給最外層的div.wrapper設置display:flex;:

图片.png

對應的程式碼如下:

<div class="wrapper">
    <div class="box"></div>
    <div class="box"></div>
    <div class="box"></div>
</div>
<style>
.wrapper{
   display: -webkit-flex; 
   display: flex;
}
</style>

接著在對中間的div.box進行規整:

图片.png

對應的程式碼修改如下:

<div class="wrapper">
    <div class="box"></div>
    <div class="box">
        <div class="top"></div>
        <div class="bottom"></div>
    </div>
    <div class="box"></div>
</div>
<style>
.wrapper{
   display: -webkit-flex; 
   display: flex;
}
</style>

我們的Flex容器為div.wrapper,Flex項目是三個div.box,div.box內部的子元素div.top、div.bottom,它們的表現形式不會發生變化,依然是默認的塊級元素展示形式,所以我們在div.box內部增加的div.top、div.bottom各占父元素的一行。

最後在將div.top、div.bottom分別拆分成兩個div.imgbox,並且給div.top和div.bottom設置display:flex:

图片.png

對應的程式碼修改如下:

<div class="wrapper">
    <div class="box"></div>
    <div class="box">
        <div class="top">
            <div class="imgbox"></div>
            <div class="imgbox"></div>
        </div>
        <div class="bottom">
            <div class="imgbox"></div>
            <div class="imgbox"></div>
        </div>
    </div>
    <div class="box"></div>
</div>
<style>
.wrapper{
   display: -webkit-flex; 
   display: flex;
}
.wrapper .box .top, .wrapper .box .bottom{
    display: -webkit-flex; 
    display: flex;
}
</style>

那麼此時整個頁面的布局工作基本完成了。接下來,我們將對應的圖片引入:

<div class="wrapper">
    <div class="box">
        <img src='./1.png'/>
    </div>
    <div class="box">
        <div class="top">
            <div class="imgbox">
                <img src='./3.png'/>
            </div>
            <div class="imgbox">
                <img src='./4.png'/>
            </div>
        </div>
        <div class="bottom">
            <div class="imgbox">
                <img src='./5.png'/>
            </div>
            <div class="imgbox">
                <img src='./6.png'/>
            </div>
        </div>
    </div>
    <div class="box">
        <img src='./2.png'/>
    </div>
</div>

刷新頁面,大致的效果就已經出來了:

图片.png

有沒有瞬間覺得Flex布局真香~

接著就是按照設計稿簡單調整一下間距就可以了。如果我們需要做自適應,那還需要給圖片設置一個百分比:

.box img{
    width: 100%;
}

最終的自適應效果:

2.gif

彈性布局對於本應用有點曲線救國的感覺,它真正更強大的可應用的地方有更多,比如我們前面提到12宮格頁面布局,就可以用Flex布局來實現,更多有關Flex布局的應用大家自行就探索吧~

4.4 百分比布局

假如我們有一個尺寸為1200*562的圖片,如果不對圖片設置的尺寸做任何限制,當瀏覽器的螢幕寬度小於1200px時,瀏覽器就會出現橫向的滾動條:

图片.png

當螢幕寬度大於1200px時,瀏覽器左側就會有空白:

图片.png

那如何讓這張圖片橫向鋪滿整個瀏覽器,既不會在小尺寸的螢幕上出現滾動條,也不會在大尺寸的螢幕上出現留白呢?

百分比布局就可以幫我們輕鬆這個解決。

對於前面的那張圖片,不管在什麼在多大尺寸的瀏覽器中,我們為其設置一個百分比寬度,讓其在當前尺寸的瀏覽器中橫向鋪滿瀏覽器,不出現滾動條也不留白:

图片.png

這個時候,我們的圖片就會適應各種尺寸的螢幕,不會出現滾動條,也不會留白:

4-.gif

如果對於其他元素我們也想實現這樣的效果,就可以將其寬度設置為一個百分比數據,這樣就能實現自適應的效果。

為元素設置百分比的寬度後,高度就不需要在進行設置了,高度會按照比例自行調節

4.5 文本溢出

在很久很久以前,做文本溢出的時候我都是採用字元串截取然後在拼接······的方式。後面一直沒有去更新這方面的技能,傻傻的用了很久。直到這次get到了實現文本溢出的新技能,所以將內容總結如下。

4.5.1 單行文本溢出

我們有下面這樣一段文本:

<p>Hello大家好,我是小土豆,關注"不知名寶藏程式媛"第一時間獲取最新文章</p>
<style>
p{
    padding: 10px;
    border: 1px dashed rgb(100, 98, 98);
    color: rgb(100, 98, 98);
}
</style>

如果p元素的寬度能夠容納這行文本,文本內容正常就在一行展示:

图片.png

此時p元素的width為600px

如果p元素的寬度無法容納這行文本,文本內容就會自動換行展示:

图片.png

此時p元素的width為500px,而且沒有設置元素的高度

那這個時候如果我們想讓內容其單行顯示,並且多餘的內容使用······代替,要怎麼實現呢?

其實也非常簡單,三個CSS屬性就能輕鬆解決:

p{
    padding: 10px;
    border: 1px dashed rgb(100, 98, 98);
    color: rgb(100, 98, 98);
    width: 500px;
    /* 以下便是解決單行文本溢出的三個CSS屬性 */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis; 
}

其中white-space屬性可以控制p元素內的文本內容不換行:

图片.png

overflow: hidden;可以讓溢出的部分隱藏起來:

图片.png

text-overflow: ellipsis;就可以設置用省略號顯示溢出且未顯示的那部分內容。

图片.png

4.5.2 多行文本溢出

下面有一段文本:

<p>Hello大家好,我是小土豆,關注"不知名寶藏程式媛"第一時間獲取最新文章|Hello大家好,我是小土豆,關注"不知名寶藏程式媛"第一時間獲取最新文章|Hello大家好,我是小土豆,關注"不知名寶藏程式媛"第一時間獲取最新文章</p>
<style>
p{
    padding: 10px;
    border: 1px dashed rgb(100, 98, 98);
    color: rgb(100, 98, 98);
    width: 500px;
    line-height: 30px;
}
</style>

默認在瀏覽器中的展示結果:

图片.png

實現多行文本溢出最簡單方法的就是用純CSS來實現:

p{
    padding: 10px;
    border: 1px dashed rgb(100, 98, 98);
    color: rgb(100, 98, 98);
    width: 500px;
    line-height: 30px;
    /* 純css實現多行文本溢出的四個必要屬性 */
    -webkit-line-clamp: 3; 
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow : hidden;
}

其中-webkit-line-clamp就是用來控制文本顯示的行數,設置為3表示文本內容只顯示3行。

給p元素設置這四個必要屬性以後,我們來看看效果如何:

图片.png

咦,出現了意外狀況,最後一行的文字似乎被截斷了導致第四行的部分內容顯示出來了。不要慌,這個時候我們將p元素的行高調整成35px就可以了:

图片.png

看到很多文章說-webkit-line-clamp屬性是一個非標準屬性,只適用於webkit內核的瀏覽器。但實際上我在Firefox和Microsoft Edge中做了測試,發現是可以實現多行文本溢出的效果;只有IE瀏覽器不支援。(尤大都官宣Vue3將不再支援IE11了,所以暫且認為這個方案是成功的 O(∩_∩)O哈哈~)

當然實現文本溢出的方法還有很多,這裡只列出來了最簡單便捷的方法,其他的方法大家感興趣的可以自行研究~

4.6 滑鼠懸浮顯示遮罩

滑鼠懸浮顯示遮罩的實現方式一般都是在目標懸浮元素的同級寫一個隱藏的元素,然後通過:hover讓隱藏的元素顯示出來。

隱藏元素一般都會採用絕對定位,所以這個例子也是前面絕對定位的一個應用。

首先我們先寫下面這樣一段程式碼:

<div class="wrapper">
    <div class="target">
        div.target
    </div>
    <div class="mask">
        div.mask
    </div>
</div>
<style>
.target{
    width: 120px;
    height: 120px;
    padding: 10px;
    background-color: #ccc;
    color: #fff;
}
.mask{
    width: 120px;
    height: 120px;
    padding: 10px;
    background-color: rgb(192, 53, 53);
    color: #fff;
}
</style>

上面程式碼的內容非常簡單,就一個父元素div.wrapper包裹這兩個同級子元素:div.target和div.mask;除此之外,我們還給子元素設置了寬高、內邊距、字體顏色和背景色這幾個常規的樣式屬性。

所以上面的程式碼在瀏覽器中展示效果如下:

图片.png

那現在我們的目標就是:滑鼠懸浮在div.target的時候顯示div.mask。

4.6.1 第一步

第一步我們先調整div.mask的位置:將其調整到div.target的位置,並且與之重合。

那這一步考察的就是CSS的定位,大致的思路就是:父元素div.wrapper設置相對定位,子元素div.mask設置絕對定位並且按照需要調整偏移量。

/* 省略前面給子元素設置的`寬高`、`內邊距`、`字體顏色`和`背景色`這些樣式屬性 */
.wrapper{
    position: relative;
}
.mask{
    position: absolute;
    top:0px;
}

注意這裡的樣式省略了前面設置的一些基礎屬性,只將這一步新增的樣式貼出來了。

之後瀏覽器查看:

图片.png

可以看到第一步已經完成了。

4.6.2 第二步

第二步就是隱藏div.mask:

/* 省略前面給子元素設置的`寬高`、`內邊距`、`字體顏色`和`背景色`這些樣式屬性 */
.mask{
    position: absolute;
    top: 0px;
    display: none;
}

图片.png

4.6.3 第三步

第三步也是最後一步,就是實現:滑鼠懸浮在div.target元素上,讓div.mask顯示。這個需求前半句好像比較好實現,就是為div.target添加偽類:hover,但是如何在div.target:hover的時候讓它的同級兄弟元素div.mask顯示呢?

那這個問題使用CSS的相鄰兄弟選擇器(Adjacent sibling selector)就能實現:

.target:hover + .mask{
    display: inline-block;
}

以上程式碼完成後,我們看看效果:

3-hover闪烁.gif

這個結果似乎是有了,但是卻不盡人意,當我們在div.target元素上移動滑鼠,div.mask出現了閃爍。

這個問題說來剛開始也很困惑,不過因為時間的關係就沒有在深入研究其原因,而是找了個別的辦法規避了。 最近在做回顧的時候又思路了一番,大致猜測了一下原因:當滑鼠懸浮在div.target上的時候,div.mask元素顯示;當滑鼠發生移動,滑鼠監測當前懸浮在div.mask元素上,那這個時候div.target:hover就失效了,失效的結果就是div.mask隱藏;當div.mask隱藏以後,div.target:hover又生效,div.mask又顯示出來了。在滑鼠移動時,這個過程就在循環執行,所以就出現了div.mask的閃爍。

後面就這個問題探索到了很多種解決方案,一 一給大家列出來。

第一個解決方案就是將目標hover元素由div.target改為它的父元素div.wrapper。

因為我們的父元素div.wrapper是默認的塊級元素,並且沒有設置尺寸,因此它默認展一整行,所以div.wrapper:hover的範圍是一整行。所以第一個方案還需要對父元素的尺寸進行控制,可以直接給父元素設置寬度,或者為父元素設置屬性display:inline-block;

.wrapper{
    position: relative;
    display: inline-block;
}
/* CSS選擇器由「子元素選擇器」變為「子元素選擇器」 */
.wrapper:hover > .mask{
    display: inline-block;
}

其他樣式程式碼不變

第二種方案是為div.mask設置pointer-events: none;,保持hover依然定義在div.target元素上。

.wrapper{
    position: relative;
}
.mask{
    /* 省略其餘樣式程式碼 */
    pointer-events: none;
}
/* hover目標元素依然是div.target */
.target:hover + .mask{
    display: inline-block;
}

5. Django和Django Admin

django是一個python web框架,它是一個和MVC非常接近的MVT框架:

图片.png

而且內部自帶開發伺服器、一個名為SQLite的輕量級資料庫和一個後端管理系統django admin,安裝和使用也比較簡單,總體來說對一個前端開發者還是非常友好的。

介於本次官網的文章管理功能不是很複雜,UI上面也沒有任何的要求,只需要實現兩個基礎的功能:登錄和文章的發布和編輯,所以就用Django框架實現後台管理系統。

關於Django的安裝和簡單使用可以移步 官網 或者 菜鳥教程,那這裡直接開始整理本次項目中使用Django的一些重要步驟。

5.1 創建項目

本地的python和django環境安裝好以後,cmd命令行執行django-admin startproject 項目名稱可以創建一個項目:

图片.png

項目創建成功後,進入項目根目錄,在項目根目錄執行django-admin startapp 模組名稱可以創建細分的功能模組:

图片.png

使用django-admin startapp命令創建細分的功能模組後,一定要將該模組配置到settings.INSTALLED_APPS中:

   # 程式碼位置:/mySystem/mySystem/settings.py
   INSTALLED_APPS = [
        # ...省略部分程式碼
       'article'
   ]

接著在項目根路徑下執行python manage.py runserver 8888就可以啟動後端服務。命令執行以後,控制台如果列印如下資訊,證明後端服務啟動成功:

项目启动成功.png

後端服務啟動成功以後,控制台的資訊已經告訴我們該服務的地址為://127.0.0.1:8888,那我們在瀏覽器中訪問這個URL就能看到django服務提供的默認頁面:

图片.png

5.2 默認數據表生成

接著我們需要創建admin管理系統相關的默認數據表,即在項目根目錄下執行python manage.py migrate:

图片.png

完成之後,瀏覽器中輸入//127.0.0.1:8888/admin就可以訪問django提供的admin管理系統:

图片.png

進入admin管理系統是需要登錄的,所以我們接下來我們要做的事就是為admin管理系統創建一個帳號。

創建帳號依然是在項目根路徑下執行python manage.py createsuperuser,接著在命令行輸入用戶名、郵箱、密碼和確認密碼,就可以成功創建出一個帳號。

图片.png

之後我們就可以用這個帳號登錄django admin後台管理系統,以下是登錄成功之後的頁面:

图片.png

到這一步是有沒有驚奇的發現後台管理系統的第一個功能登錄已經完成了╰(°▽°)╯。

5.3 數據表基礎操作

第一個功能我們已經在不經意間完成了,那接下來就是文章的發布和編輯了。

首先我們需要創建一張數據表,在django框架中,創建數據表的第一步是創建一個models類:

# *_*coding:utf-8 *_*
from django.db import models

# Create your models here.
class Article(models.Model):
    a_id = models.AutoField(primary_key=True, verbose_name="編號")  # 文章編號 主鍵 自動生成
    a_text = models.TextField(verbose_name="正文內容")   # 文章內容
    class Meta:
        verbose_name_plural='文章'

程式碼位置:/mySystem/article/models.py,使用djang-admin startapp創建article模組時會自動生成models.py文件。
程式碼中的verbose_name和verbose_name_plural分別為欄位和數據表定義中文名稱,所以後面我們看到的article數據表和表中的欄位都會是中文的;如果不配置這兩個屬性,默認顯示的是英文。

之後在項目根目錄下分別執行python manage.py makemigrations和python manage.py migrate命令:

图片.png

python manage.py makemigrations會根據models.py文件中定義的數據表和欄位生成對應的數據表初始化文件,即/mySystem/article/migrations/0001_initial.py;後者會根據生成的0001_initial.py文件創建數據表;如果後期表結構發生變化,先修改models.py,在重複執行這兩個命令即可。

以上兩個命令執行成功後,數據表就已經創建出來了,接著我們還需要將這個數據表註冊到admin中:

# *_*coding:utf-8 *_*
from django.contrib import admin
from article.models import Article

# Register your models here.
admin.site.register(Article)

程式碼位置在:/mySystem/article/admin.py,創建article模組時會自動生成admin.py。

這個時候我們在刷新頁面就能看到我們剛剛創建的article數據表了:

图片.png

數據表註冊到admin中這一步是不能缺少的,否則admin管理系統是不會顯示article這個數據表的

5.4 數據表訂製

對於我們剛剛創建的article數據表,點擊頁面的+Add按鈕,輸入正文內容,點擊右下角的SAVE按鈕就可以新增一條文章:

图片.png

models.py中只定義了兩個欄位編號(a_id)和正文內容(a_text),其中編號是自增主鍵,所以我們在新增文章的時候,只需要填入正文內容即可。

點擊ARTICLE或者文章,可以查看錶中的數據:

图片.png

勾選列表中的複選框,點擊動作右側的下拉框,選擇刪除所選的文章就可以刪除文章:

图片.png

點擊文章的編號就能修改對應的文章內容:

图片.png

以上就是文章的增、刪、改、查操作,也是我們整個後台管理系統需要實現的第二個功能。

不過從以上的結果可以發現列表顯示Article Object而不是具體的數據,而且除了前面我們給數據表和欄位設置的中文以外,其他的操作按鈕均是英文的。

這個兩個問題其實是admin管理系統的默認顯示,當然我們也可以對這些顯示做一些訂製。

5.4.1 列表展示具體欄位

想讓列表顯示具體的欄位,第一種方法就是為article 模型定義__str__方法並返回想要顯示的欄位:

# *_*coding:utf-8 *_*
from django.db import models

# Create your models here.
class Article(models.Model):
    a_id = models.AutoField(primary_key=True, verbose_name="編號")  # 文章編號 主鍵 自動生成
    a_text = models.TextField(verbose_name="正文內容")   # 文章內容
    class Meta:
        verbose_name_plural='文章'
    def __str__(self):
        return self.a_text

這個時候在刷新文章列表就能看到效果:

图片.png

另外一種方法就是在為article定義對應的ArtcileAdmin類,並且在list_display設置列表需要展示的欄位即可,最後在將ArticleAdmin註冊到admin中:

# *_*coding:utf-8 *_*
from django.contrib import admin
from article.models import Article

# 為article模型定義對應的ArtcileAdmin
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('a_id','a_text')  # 設置列表需要展示的欄位

# Register your models here.
admin.site.register(Article, ArticleAdmin) # 將ArticleAdmin也註冊到admin中

程式碼位置在:/mySystem/article/admin.py

最後我們看下效果文章列表:

图片.png

可以看到列表已經成功的顯示了我們定義的內容。

5.4.2 中文配置

為了方便我們的操作,一般會將頁面配置成中文模式的,那admin管理系統的中文模式也非常好實現,直接在settings.py文件中定義一個中間件即可:

MIDDLEWARE = [
    'django.middleware.locale.LocaleMiddleware'
]

程式碼位置在:/mySystem/mySystem/settings.py

配置完成以後,在刷新頁面就能看到中文模式的admin管理系統。

图片.png

5.5 功能二次開發

數據表訂製完成以後,你以為就結束了嗎?no no no,前面我們實現的文章功能太簡單了,只能以純文本的形式編輯文章的正文內容,所以接下來我們就需要在這個基礎上對文章的新增和編輯功能做一個二次開發。

一般情況下,一篇文章包含的欄位至少包含:文章標題、文章作者、發布時間、正文內容、文章封面等這些內容,而所以需要對文章的新增和編輯進行二次開發;而文章的列表展示和刪除功能都是比較簡單的操作,現有的功能已經可以滿足。

從瀏覽器中我們可以看到新增文章頁面url為
//127.0.0.1:8888/admin/article/article/add/:

图片.png

那麼我們就可以自己配置一個路由為:/admin/article/article/add/,然後編寫對應的視圖文件和模板文件。

首先我們需要在主路由文件中配置路徑:

from django.contrib import admin
from django.urls import path

from django.urls import include # 新增程式碼
import article
urlpatterns = [
    path('admin/article/', include('article.urls')), # 新增程式碼
    path('admin/', admin.site.urls),
]

程式碼位置:/mySystem/mySystem/urls.py,新增的程式碼在備註中有說明
該文件為整個項目的主路由文件,所有的請求url都從這裡開始分發,一般為了項目的模組化和更好的分工,會將不同模組的路由到對應模組的urls.py文件中,

接著將後半部分路徑配置到article模組下的路由文件中:

from django.urls import path

from article import views

urlpatterns = [
    path('article/add/', views.addArticle),
]

程式碼位置:/mySystem/article/urls.py

然後我們編寫對應的視圖函數:

from django.shortcuts import render

# Create your views here.
def addArticle(request):
    return render(request, 'add.html', {})

程式碼位置:/mySystem/article/views.py

視圖文件中我們針對/admin/article/article/add/請求渲染了一個模板文件add.html,所以我們還需要創建對應的模板文件。

首先在/mySystem/article/創建文件夾templates:

图片.png

接著在templates目錄下創建add.html:

图片.png

我們在add.html中寫入一些簡單的內容:

<p>新增一些文章吧</p>

最後一步還需要在settings.py中對模板文件的位置進行配置:

import os # 新增
TEMPLATES = [
    {
        # 省略程式碼...
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        # 省略程式碼...
    },
]

程式碼位置:/mySystem/mySystem/settings.py

這個時候我們在刷新頁面:

图片.png

我們會發現新增頁面已經路由到了我們自定義的add.html,這個時候我們就可以在add.html中自由發揮了,比如新增表單控制項、嵌入富文本編譯器等等。

對於文章的編輯功能也是同樣的方法,先找到編輯功能的完整URL://127.0.0.1:8888/admin/article/article/2/change/。

图片.png

仔細分析這個URL會發現這個URL中有一個參數是變化的,那就是文章的編號,所以我們的路由配置必須要用正則才能進行匹配:

from django.urls import path, re_path
from article import views
urlpatterns = [
    path('article/add/', views.addArticle),
    re_path('article/(\d+)/change/', views.updateArticle), # 正則路徑 
]

程式碼位置在: /mySystem/article/urls.py
需要注意的是,本地搭建的django版本為3.x,所以正則路由是需要使用re_path來配置;如果是django 1.x版本,不管是普通路由還是正則路由,均可使用url匹配即可,詳細可參考官方文檔。

接下來就是為文章編輯功能編寫對應的視圖函數和模板文件即可,這塊同前面的新增功能,所以就不在多說了。

因為我們對新增和編輯功能進行二次開發,那同時還需要實現對應的提交保存資料庫邏輯。比如我們的文章新增功能,在add.html中新增表單後,需要有對應的提交功能,這個提交功能就是將用戶填寫的文章資訊提交並保存到資料庫。那這個功能同樣是先配置路由:

from django.urls import path, re_path
from article import views
urlpatterns = [
    path('article/submitAdd', views.submitAdd) # 將文章內容保存到資料庫
]

程式碼位置在:/mySystem/article/urls.py
這裡省略了前面配置的文章新增和文章編輯路由

然後在編寫對應的視圖函數submitAdd。

以上兩個步驟完成以後,前端在提交表單時的url為:/admin/article/article/submitAdd,用戶填寫好內容點擊提交後,後端就會將數據保存到資料庫中。

5.6 小結

那到這裡整個後端功能就結束,大部分功能都我們藉助了django admin,同時對文章新增和文章編輯功能做了二次開發。

如果在整個項目中後端功能比較複雜且UI要求比較高,那我們可能就得自己從0開始實現一個後台管理系統,對於後台管理系統最基礎且重要的功能就是登錄功能,關於這個功能我之前也有過總結,是用django+vue實現的項目,詳細可以查看以下兩篇文章:

《Vue結合Django-Rest-Frameword實現登錄認證(一)》

《Vue結合Django-Rest-Frameword實現登錄認證(二)》

6. 項目部署

項目部署也不是什麼複雜的事情,只是在這一步也有一些需要注意的東西。

6.1 後端項目部署

對於後端項目,伺服器也是需要提供python和django框架,安裝教程這裡就不說了,可自行在網上搜索。

但是需要注意的是,最好是先確定好伺服器端的python版本和django版本,因為不同版本的django需要不同的python版本支援:

图片.png

Django 1.x使用python2的環境即可

這裡解釋一下為什麼需要先確定伺服器上的環境版本。
有些時候我們使用的伺服器有可能已經存在python環境,如果是python2的環境,那django只能選擇1.x的版本;
如果是python3的環境,那django版本的選擇就沒有什麼限制;
還有大多時候伺服器會並存python2和python3,這個時候我們還是需要抉擇用哪個python版本。

假如我們直接先在本地去搭建,就可能存在本地環境和伺服器環境軟體版本不一致的問題。

確定好伺服器中軟體的版本以後,我們本地搭建環境就和伺服器保持一致,編寫完功能以後就可以將本地整個目錄程式碼拉到伺服器中的某個目錄下,後續也不會因為版本問題導致本地測試正常而伺服器報錯的問題。

本地程式碼拉到伺服器上以後,在伺服器項目根目錄下執行python manage.py migrate,就能生成對應的數據表,並且還能將本地開發環境中生成的有關資料庫的測試數據同步到伺服器。

在同步本地開發環境中生成的有關資料庫的測試數據之前,需確保本地生成了資料庫初始化文件,生成該文件的方法前面已經說過,就不在贅述。

這些準備工作完成以後,如果是自己練習的項目,可以直接啟動django內置的server即可,整個後端項目就算部署完成;如果是公司級別的項目,最好用在伺服器中安裝Apache和mod_wsgi來部署項目。

6.2 前端項目部署

前端部署項目非常簡單,在伺服器安裝nginx即可,然後將編譯打包後的程式碼源碼上傳至伺服器的某個位置,在修改nginx的配置文件nginx.conf:

server {
    listen 80;  # 通過那個埠訪問前端網頁
    server_name localhost;

    location / {
        root /var/www/lr/;   # 前端編譯打包後的程式碼路徑
        try_files $uri $uri/ /index.html;
        index index.html index.htm;
    }
    location /admin/ {  # 將以/admin/開頭的請求轉發到proxy_pass 配置的服務
        proxy_pass //127.0.0.1:8888/admin/; # 後端服務路徑
    }
}

7.問題解決

7.1 部署樣式出現問題

前端的功能本地開發好以後,就開始部署到伺服器上,但是發現很多自定義的樣式沒有生效。但是瀏覽器查看元素會發現能看到我們自定義的樣式,但是它的優先順序比較低,被element-ui的樣式給覆蓋了。

這個問題最合適的解決方案就是將main.js中element的樣式文件引入順序放到App組件的前面:

import 'element-ui/lib/theme-chalk/index.css'
import App from './App'

7.2 hover閃爍問題

滑鼠懸浮顯示遮罩導致的hover閃爍問題前面我們已經做過總結,這裡就不在重複,僅僅將這個問題列出來。

其實整個過程中也不止這兩個問題,其他出現的問題在前面一些部分寫到了注意事項中,所以這裡就沒有總結;還有一部分是當時出現問題的時候沒有記錄,現在回想不起來了o(╥﹏╥)o

8.結束

那到此整個項目就總結完了,沒有什麼特別複雜的地方,但是也有一部分內容讓我學習到了新的技能。

當然整個過程中不止技術上的進步,更有血和淚的教訓,所以後面一篇文章會對這次的項目做一個經驗教訓總結,所以下次見嘍~

9. 寫在最後

如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者

文章公眾號首發,關注 不知名寶藏程式媛 第一時間獲取最新的文章

筆芯❤️~