第一節
@注意
千萬注意格式、標簽名字;
瀏覽器開發者模式修改頁面不顯示:在開發者模式下(F12進入),打開設置頁面(F1),勾選 Disable cache (while DevTools is open)
即可;
提示沒有修改頁面的權限,在pycharm的debug里面勾選allow unsigned requests;
html用chrome演示;
pycharm顯示pip19版本但是turminal是9版本:進入第三方庫目錄,刪掉pip19info文件夾,重新python -m pip install --upgrade pip;
@坑
php建站后使用比較麻煩
計算機基礎
英語基礎
@前后端分離
vuejs框架和django,vuejs接管django的views模塊;
django打開頁面是不停刷新,用vuejs可以不用太多跳轉;
@django的MTV
models
templates
views
@升級pip
python -m pip install --upgrade pip
@設計(Adobe xd 沒有Linux版本,找個ui設計軟件)
1.https://semantic-ui.com/ 源代碼里找到dist/semantic.min.css,即打開view-source:https://semantic-ui.com/dist/semantic.min.css並復制,保存到semantic.min.css文件中,刪除@import那一行(從@到;刪掉,刪多了會顯示錯誤);
2.在html的head里面添加<link rel="stylesheet" href="項目內路徑">
增加自己的mystyle.css,也添加到head引用;
3.設置四個導航欄(課程里四列,但是我四列就變兩行了?)
<body>
<div class="top-menu">
<div class="ui container">
<div class="ui five column grid">
<div class="column">
首頁
</div>
<div class="column">
blog
</div>
<div class="column">
作品
</div>
<div class="column">
聯系
</div>
</div>
</div>
</div>
</body>
4.打開網頁,f12,點擊手機方式瀏覽,在head連加入以下,實現移動設備優先
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
5.修改mystyle.css文件
html{
font-size:10px;
}
.top-menu{
background:#000;
color:#fff;
padding-top:1rem;/*1rem表示根元素的大小*/
}
.top-menu .column{
text-align:center;
}
6.首頁幻燈
https://www.swiper.com.cn/
找案例,看源代碼,找css引用文件並點擊打開,復制到新建的swiper.css文件中,並在html中引入樣式;從案例中復制body里面的html內容到我的html中;復制案例中的js內容並保存到我的js文件里,在html的body結束前插入引用(django里面不用這種路徑就)<script src="../statics/swiper.css" charset="utf-8"></script>
增加js自主添加的編碼,也是復制案例里面的

<script> var swiper = new Swiper('.swiper-container', { spaceBetween: 30, centeredSlides: true, autoplay: { delay: 2500, disableOnInteraction: false, }, pagination: { el: '.swiper-pagination', clickable: true, }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev', }, }); </script>
調整網頁
<div class="swiper-slide">Slide 6</div>
替換為
<div class="swiper-slide"><img src="路徑" alt=''></div>
調整mystyle.css
positon:fixed;位置為懸浮
heigh:3000px;框架高度
top:0;上邊距
z-index:999;位於最高
width:100%;
height:3rem;(html{}里面font-size:10px;rem是font-size的倍數)
發現導航欄擋了一部分banner圖(用一下方法,或直接在html里面將導航欄的透明度更改一下)
在之間創建一個div,id=’banner'
css里面創建
#banner{ margin-top:5rem }
刪除輪播圖的箭頭(刪掉“<!-- Add Arrows --><div class="swiper-button-next"></div><div class="swiper-button-prev"></div>”)
7.做功能按鈕
圖片來源https://www.iconfont.cn/ 新浪微博登錄 圖片都改為拼音不用中文;
文章簡圖 創客貼;
8.放入django
@創建項目,創建app,配置settings:
注冊app;
STATIC_URL = '/statics/' MEDIA_URL='/upload/' MEDIA_ROOT=os.path.join(BASE_DIR,'upload').replace('//','/')
@修改urls
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
from myblog import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index),
]+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) \
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
@migrate一下
@配置views.py里面的index
def index(request): return render(request,'index.html')
@處理載入問題
引入模板{% load static %}
配置鏈接
<link href="{% static "css/semantic.min.css" %}" rel="stylesheet"> <link href="{% static "css/mystyle.css" %}" rel="stylesheet"> <link href="{% static "css/swiper.min.css" %}" rel="stylesheet">
相關的圖片和js的引用也用類似格式修改
9.配置admin后台
配置models,創建首頁模塊
class Topmenu(models.Model): #blank就是空的也可以存,default默認為空 title=models.CharField(default='',blank=True,null=True,max_length=20) url=models.CharField(default='',blank=True,null=True,max_length=20) def __str__(self): return self.title
@創建超級用戶python manage.py createsuperuser(用戶名字前倆,密碼s)
@注冊首頁模塊
from django.contrib import admin from myblog.models import Topmenu admin.site.register(Topmenu)
注冊了賬戶就需要合並數據庫,add首頁導航欄幾個名字,只寫title
@處理views
from django.shortcuts import render from .models import Topmenu # Create your views here. def index(request): topmenu=Topmenu.objects.all() content={ 'topmenu':topmenu } return render(request,'index.html',content)
@處理html,載入數據庫中的導航欄名稱
{% for item in topmenu %} <div class="column"> {{ item.title }} </div> {% endfor %}
10.vue.js
@兩種方式引入,開發用開發版本,會有報錯提示
<!-- 開發環境版本,包含了有幫助的命令行警告 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
或者:
<!-- 生產環境版本,優化了尺寸和速度 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
@引用vue.js
復制第一個引用鏈接,瀏覽器打開,復制所有,在項目中創建vue.js文件;
html的head中插入
<script src="{% static 'js/vue.js' %}" charset="utf-8"></script>
刷新頁面,查看開發者模式控制台,有(
)表示引用成功。創建index.js並引用,先空着。
@編輯index.js
new Vue({ // el就是element el:'#index', data:{ // js語法:數組表示為中括號,對象用大括號 topmenu:[{title:'首頁'},{title:'blog'},{title:'作品'},{title:'聯系'},] }, })
提示vue不能獲取id,則說明頁面中script加入的位置太靠前,應該放在要顯示的位置的后面。
提示
,則說明script放在</div>前面了。html中用<div v-for='item in topmenu' class="column">代替原來的for循環,此時不顯示,body和script之間加入{% verbatim %}接管django,
@django模式的標簽地址屬性改為vuejs用的。
原為:
<img src="{static ‘image/77263a9a-6416-4131-a10e-c43ba516170d.jpg’}">
后為:
<img src="static/image/77263a9a-6416-4131-a10e-c43ba516170d.jpg">
@Ajax
https://www.npmjs.com/package/reqwest
@創建路由,在myblog子app里面創建api.py,下載djangorestframework,並在settings里面注冊子app 'rest_framework'
@修改api.py
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.decorators import api_view
from myblog.models import Topmenu
class Topmenuxuliehua(serializers.ModelSerializer):
class Meta:
depth=1
model=Topmenu
fields='__all__'
@api_view(['GET'])
def indexData(request):
print('ok')
return Response('ok')
@增加路由
path('api/index', api.indexData),
刷線如下圖
這就是rest_framework為django提供的json格式界面,點擊get里面的json可查看json格式數據。
@頁面載入js數據
def indexData(request): topmenu=Topmenu.objects.all() topmenuData=Topmenuxuliehua(topmenu,many=True) return Response({'topmenu':topmenuData.data})
此時頁面就可以讀取js數據
@引用reqwest.js
復制reqwest文件到js文件夾中,引入到index頁面的頭部。
修改index.js
new Vue({ // el就是element el:'#index', data:{ // js語法:數組表示為中括號,對象用大括號 topmenu:[{title:'首頁'},{title:'blog'},{title:'作品'},{title:'聯系'},] }, methods:{ getData:function(){ reqwest({ url:'/api/index', method:'get', success:function(data){ console.log(data) } }) } } })
此時頁面可在開發者模式的console頁看到沒有成功執行console.log(data),需要添加方法
// mounted方法是載入html時最先執行的方法 mounted(){ console.log('ok') this.getData() },
js可以正常工作
@修改index.js
new Vue({ // el就是element el:'#index', data:{ // js語法:數組表示為中括號,對象用大括號 topmenu:[] }, // mounted方法是載入html時最先執行的方法 mounted(){ this.getData() }, methods:{ getData:function(){ // 避免this指向錯誤,設置self var self=this reqwest({ url:'/api/index', method:'get', type:'json', success:function(data){ console.log(data) self.topmenu=data.topmenu console.log(self.topmenu) } }) } } })
網站基礎應用搭建完畢,接下來豐富網站
完整項目流程:
11.豐富網站內容
@找b站封面圖片
右擊視頻審核元素,找到上面的pic的class,復制里面的圖片地址如‘//i0.hdslb.com/bfs/archive/91ca6962927787a14e6c0043d84db702ab14bb74.jpg@160w_100h.jpg’
鏈接前面加上‘http://’,后面改下w和h的值為1140,717,依次獲得三張圖片
@修改models.py(一旦修改model層,就要更新數據庫),新增:
class Banner(models.Model): img=models.ImageField(blank=True,null=True) def __str__(self): return self.id
在admin.py 里面增加對Banner的引用,並注冊,此時admin后台頁面就顯示增加了Banner;
此時在Banner處增加圖片,報錯,提示__str__ returned non-string (type int);
將Banner里面的__str__改為__int__,網頁還不對的話,就重新啟動服務器;
因為之前配置了MEDIA_URL為‘/upload/’所以在整個項目第一層會將所有新上傳媒體文件收錄到upload文件夾中。
@將上傳圖片返回到網頁
原先models層返回到views.py,現在是返回到api.py;
新增bannerData
#Author:Wen from rest_framework import serializers from rest_framework.response import Response from rest_framework.decorators import api_view from myblog.models import Topmenu,Banner class Topmenuxuliehua(serializers.ModelSerializer): class Meta: depth=1 model=Topmenu fields='__all__' class BannerData(serializers.ModelSerializer): class Meta: # 設置depth標記,方便數據關聯 depth=1 model=Banner # 就一個img字段,所以可以用__all__,如果都選擇型顯示,可以fields=(['img','lala']) fields='__all__' @api_view(['GET']) def indexData(request): # 首頁的導航欄 topmenu=Topmenu.objects.all() topmenuData=Topmenuxuliehua(topmenu,many=True) # 首頁的Banner banner=Banner.objects.all() bannerData=BannerData(banner,many=True) return Response({'topmenu':topmenuData.data,'banner':bannerData.data})
此時刷新http://127.0.0.1:8000/api/index,可以看到返回的json數據
@api(即rest_framework)的json數據被vuejs(即index.js)獲取:index.js里面新增banner數組,設置變量獲取數據,mounted方法中新增console.log(this)
查看頁面的返回信息
可見頁面渲染需要調取banner的img屬性
@用vuejs渲染index.html
<div v-for='item in banner' class="swiper-slide">
<img :src="item.img" alt="" style="width:100%">
</div>
刷新就顯示banner圖
12.用戶賬號
@用戶的前端制作
models里面新增用戶模型
from django.contrib.auth.models import User
html修改,在{% endverbatim %}上面的</div>的上面新增
<div id="login">
<div class="userui">
<div class="ui container" style="background: #fff2f2">
<h3>登錄</h3>
<div class="input">
<div class="item">
<input type="text" name="" value="" placeholder="用戶名">
</div>
<div class="item">
<input type="text" name="" value="" placeholder='密碼'>
</div>
</div>
<button type="button" name="button">取消</button>
<button type="button" name="button" style="background: #0d71bb;color: #ffffff">確定</button>
</div>
</div>
</div>
修改css
#login{ } #login .userui{ position:fixed; top:30rem; width:100%; height: 20rem; } #login .userui .ui.container{ background: #fff; padding:1rem 1rem 1rem 1rem; border:1px solid #efefef; text-align: center; } #login .userui .ui.container .item{ width:100%; height:4rem; margin-bottom: 1rem; } /*div下面的div用點,div下面不是div用空格*/ #login .userui .ui.container .item input{ width:100%; height:100%; border:1px solid #a96216; border-radius:2rem; text-align: center; } #login .userui .ui.container button{ background: #FFFFFF; width:8rem; height:3rem; margin-left:1rem; border:1px solid #0f0f10; }
@交互
修改api.py,新增
# 用戶管理 from django.contrib.auth import login from django.contrib.auth.models import User
@讓登陸框默認隱藏
index.js--data--新增userui:false,
index.html里面找到要設置為點擊打開登陸頁面的div,新增@click='showuserui()'
index.js--methods新增(別忘了前面加逗號)
showuserui:function(){ this.userui=!this.userui }
@前端捕獲用戶賬號密碼
index.js--data新增‘username’和‘password’兩個空數據;
index.html--input標簽中新增‘v-model='username'’;
@向后台發送
index.html確定按鈕新增@click='userlogin()'
index.js新增方法
userlogin:function(){
var self=this
reqwest({
url:'/api/index',
method:'post',
data:{
username:self.username,
password:self.password
},
success:function() {
console.log('ok')
},
error:function(err){
console.log(err)
},
})
},
api.py裝飾器中增加‘POST’方法
注意:出現favicon.ico缺失錯誤
<link rel="icon" href="data:;base64,=">
@后台驗證賬號
api.py
from django.contrib.auth import login,authenticate #函數中新增 username=request.POST['username'] password=request.POST['password'] user=authenticate(username=username,password=password) print(user) if user!=None: login(request,user) return Response({'loginType':'ok'})
@處理跨站請求csrftoken
js.cookies.js文件復制到static/js文件夾中
html--在index.js引入前插入
<script type="text/javascript"> var csrftoken=Cookies.get('csrftoken') console.log(csrftoken) </script>
index.js--在userlogin方法下加入
type:'json', headers:{ 'X-CSRFTOKEN':csrftoken },
此時前端賬號登錄就能保證打開后台頁面后台也可以登錄。
@
@登錄就關閉登錄框,並且登錄按鈕改為“我的”
index.js--method-userlogin-reqwest-seccess里面新增
if(data.loginType=='ok'){ self.userui=false
index.html
<div v-if='loginButton' @click='showuserui()' class="column"> 登陸 </div> <div v-else class="column"> 我的 </div>
index.js--data--新增loginButton:true,
index.js--method-userlogin-reqwest-seccess里面if下面新增loginButton:false,
@后台驗證是否登錄
因為登錄失敗,django捕獲的request.user.id都為none,所以用此判斷登錄狀態
if userid!=None: loginType='ok'
index.js新增loginType:true??
if(data.loginType=='ok'){ self.loginType=true }else{self.loginType=false}
@13.多app的關聯
@13p
在app的templates路徑下新建app同名文件夾,將html放進去;render()后面的渲染頁面路徑為app名稱/html文件名;
在app的static路徑下新建app同名文件夾,把存放靜態文件的文件夾放進去;
新增的靜態文件需要settings內注冊地址:
STATICFILES_DIRS=[ os.path.join(BASE_DIR,'ak','static'), os.path.join(BASE_DIR,'myblog','static'), ]
html中引入靜態文件夾,修改靜態文件引入路徑為django模式路徑
14.MYSQL
@准備
pip install mysqlclient;
配置settings
下載workbench,輸入數據庫密碼,創建數據庫庫名與django里的settings一致;
創建django超級用戶;
數據遷移;
刷新頁面發現banner圖和導航欄不見了,在django官方后台提交材料;
@
15.15p
@include
15-10
@可以右鍵復制整體HTML;注意引用網頁模板的時候別落下js的引用。
@
@
@
@