Django 複習

 

 Django 基礎1css

day49html

老師的博客:
https://www.cnblogs.com/yuanchenqi/articles/6083427.html前端

http://www.cnblogs.com/haiyan123/p/7701412.htmlpython

MVC和MTV模型:jquery

著名的MVC模式:所謂MVC就是把web應用分爲模型(M),控制器(C),視圖(V,html文件)三層;他們之間以一種插件似的,鬆耦合的方式鏈接在一塊兒。web

模型負責業務對象與數據庫的對象(ORM),視圖負責與用戶的交互(頁面),控制器(C)接受用戶的輸入調用模型和視圖完成用戶的請求。數據庫

                   

Django的MTV模式本質上與MVC模式沒有什麼差異,也是各組件之間爲了保持鬆耦合關係,只是定義上有些許不一樣,Django的MTV分別表明:django

       Model(模型):負責業務對象與數據庫的對象(ORM)瀏覽器

       Template(模版,html文件):負責如何把頁面展現給用戶服務器

       View(視圖):負責業務邏輯,並在適當的時候調用Model和Template

       此外,Django還有一個url分發器,它的做用是將一個個URL的頁面請求分發給不一樣的view處理,view再調用相應的Model和Template

Django 的流程和命令行工具

安裝django

pip3 install django---->添加環境變量

建立項目(工程)

django-admin startproject p2p

---p2p(下面的文件是全局的)

  ---settings.py  配置

  ---urls.py  路由分發

  ---wsgi.py  web

---manage.py

建立應用(App),咱們的app01 的應用寫在這裏

python  manage.py startapp app01

咱們建立了一個app01 後,咱們要到全局配置p2p/settings.py 裏  INSTALLED_APPS 添加一行 「app01」

 

如今咱們給app01 這個應用添加一個show_time 的功能,由於咱們的全部的邏輯是寫在views裏,因此咱們在app01/views.py 裏定義以下函數

def show_time():
  pass

而後咱們在全局路由urls.py裏配置路由轉發規則

from app01 import views
path('show_time/', views.show_time)

django2 這裏是urls(r'show_time/', views.show_time)
django3 這裏是path


由於咱們返回的是字符串給瀏覽器,因此這裏咱們引入HttpResponse
from django.shortcuts import render,HttpResponse

def show_time(request):

return HttpResponse("hello")
咱們把全部的靜態文件放在template 目錄下,這裏咱們修改一下settings.py
註釋掉
# TEMPLATE_DIRS = (os.path.join(BASE_DIR,'templates'),)
TEMPLATES 列表裏的字典 DIRS=[] 改爲
'DIRS': [os.path.join(BASE_DIR,'templates')]

咱們的views.py 這麼寫
from django.shortcuts import render,HttpResponse
import time
# Create your views here.

def show_time(request):
    # return HttpResponse("hello world")
    local_time=time.ctime()
    return render(request,"index.html",{"time":local_time})
這裏的 {"time":local_time} 渲染給前端。前端經過{{ time }}來接收參數
templates 下的index.html 這麼寫。這裏兩個大括號的做用就是渲染 time 變量
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h1>hello bigbao {{ time }}</h1>
</body>
</html>

  

這裏咱們用前面學到的jquery知識,咱們把前端展現的字體變成紅色(錯誤示範)

一、咱們把jqeuery-3.1.1.js文件放到templates目錄下

二、index.html 作以下調整

<h1>hello bigbao {{ time }}</h1>
<script src="jquery-3.1.1.js"></script>

<script>
    $("h1").css("color","red")
</script>

三、咱們再去訪問一下,看到字體顏色沒有變化,報以下的錯誤

這裏錯誤的緣由是Django沒有找到這個jquery文件

這裏咱們應該在項目裏面建立一個static目錄(和應用同級),這個咱們後面放js,css,img

而後咱們把jquery文件放在staic目錄下,而後咱們在settings.py 裏進行配置,讓Django知道靜態文件放在哪裏了

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]

這裏必須用 STATICFILES_DIRS 這個名字,同時別忘了 逗號

 這裏說一個問題,我一開始試驗的時候,我這裏建立的目錄的名字是statics ,而後我這裏配置的是

STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'statics'),]

可是訪問的時候仍是404,我這裏用上面那種方法就是能夠用的。如今咱們解釋一下

STATIC_URL  和  STATICFILES_DIRS
STATICFILES_DIRS 是告訴Django 的static的絕對路徑,可是引用的時候用的是STATIC_URL
# STATIC_URL 是別名,之後實際用的時候用的是這個別名,STATICFILES_DIRS 是Django用的,STATICFILES_DIRS 和 STATIC_URL 必須都存在,結合使用的
# 咱們在用STATIC_URL別名的時候,Django 會本身去找到他的實際路徑,咱們在html應用靜態文件的時候必須用別名,好比
# <script src="/static/jquery.js"></script>

# 文件的實際存在目錄,必須叫STATICFILES_DIRS

 因此咱們index.html 用下面的方式就能夠改變頁面的字體顏色了

<h1>hello bigbao {{ time }}</h1>
<script src="/static/jquery-3.1.1.js"></script>    這裏的static用的是配置文件的別名

<script>
    $("h1").css("color","red")
</script>
再說一下上面的問題,假如說咱們的靜態文件的真實路徑的名字是 bigbao_static 那麼這裏咱們的settings.py配置是這樣的
-------------------------------------------------------------------------------------------
STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'bigbao_static'),]

-------------------------------------------------------------------------------------------
html 文件是這樣的
<h1>hello bigbao {{ time }}</h1>
<script src="/static/jquery-3.1.1.js"></script>

<script>
    $("h1").css("color","red")
</script>

由於這裏咱們的別名是static,記住這句話 STATIC_URL 和 STATICFILES_DIRS 是想呼應的,STATICFILES_DIRS 是給Django用的,他去找真實的路徑,STATIC_URL別名是給後面項目實際調用的 因此咱們在html文件裏要是寫真實的靜態文件路徑是不行的

<script src="/bigbao_static/jquery-3.1.1.js"></script>

還有一種方案就是load,後面推薦使用的,可是咱們剛剛前面配置的STATIC_URL 和 STATICFILES_DIRS不能註釋掉,咱們在html文件裏這麼寫

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
 {% load staticfiles %}     <title>Title</title>
</head>
<body>

<h1>hello bigbao {{ time }}</h1>
{#<script src="/static/jquery-3.1.1.js"></script>#}
{% static "jquery-3.1.1.js" %} <script>
    $("h1").css("color","red")
</script>

</body>
</html> 

其實在實際工做中咱們應該把每一個app的靜態文件放在本身應用的目錄下面,因此這裏咱們在本身的應用目錄下面app01建立一個static目錄

而後配置settings.py   STATICFILES_DIRS=[os.path.join(BASE_DIR,"app01","static")]

Django的URL控制系統

URL 的無名分組和有名分組

from app02 import views
from django.conf.urls import url

urlpatterns = [
  #無名分組     url(r'^article/\d{4}', views.year) ,

    url(r'^article/(\d{4})$', views.year2),
    若是有多個匹配同樣的時候,誰放在上面就匹配誰,上面的就會把下面的覆蓋了
    正則加上括號,就是分組,會把分組的內容做爲year2函數的參數傳進去
    url(r'^article/(\d{4})/(\d{2})$', views.year_month),
 # 有名分組(就是給分組起個名字,這樣定義的好處就是按照關鍵字參數去傳參了,指名道姓的方式)
    url(r'^article/(?P<year>\d{4})/(?P<month>\d{2})$', views.year_month_hasname)

  

 捕獲的值做爲關鍵字參數而不是位置參數傳遞給視圖函數。例如:

/articles/2005/03/    
    請求將調用views.month_archive(request, year='2005', month='03')函數

  

這裏咱們也一個簡單的註冊頁面;

urls.py
    path('register/', views.register,name="reg"),
這裏的name 是一個別名,後面用這個別名
----------------------------------------------------------------------------------------------------------------------------------views.py-------------------------------------------def register(request,*args,**kwargs):
    if request.method == "POST":
        # print(request.POST.get('username'))
        print(request.POST)
        return HttpResponse("Success")

    return render(request,"register.html")
----------------------------------------------------------------------------------------------------------------------------------register.html--------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        h1{
            text-align: center;
        }
    </style>
</head>

<body>
<h1>註冊系統</h1>

<form action="{% url 'reg' %}" method="post">
{#<form action="/register" method="get">#}
{#    這倆action 路徑寫死了,這個時候咱們應該在 urlpattern 上家一個別名#}
    <p>姓名<input type="text" name="username"></p>
    <p>年齡<input type="text" name="age"></p>
    <p>愛好<input type="checkbox" name="hobby" value="1">籃球
        <input type="checkbox" name="hobby" value="2">網球
        <input type="checkbox" name="hobby" value="3">足球
    </p>
    <p><input type="submit" value="提交數據"></p>
</form>

</body>
</html>

 

實際環境中咱們應該根據應用來分發URL,因此這裏咱們應該用URLConf

操做方式是:

咱們在項目下的主路由urls.py作以下修改

from django.urls import path  改爲  from django.urls import path,include
path('app01/', include('app01.urls'))  全部已app01 開頭的都跳到app01.urls路由

 而後咱們到app01 下建立urls.py文件

from django.urls import path
from app01 import views

urlpatterns = [
path('register/', views.register,name="reg"),
]

這個時候咱們就不能用剛的方式去訪問了http://127.0.0.1:8000/register/這樣是訪問不到的
咱們得用這種方式 http://127.0.0.1:8000/app01/register/


view(視圖)和template(模板)day50
http請求產生兩個核心對象
httpRequest
httpResponse
HTTPRequest的屬性和方法:
# path:       請求頁面的全路徑,不包括域名
#
# method:     請求中使用的HTTP方法的字符串表示。全大寫表示。例如
#
#                    if  req.method=="GET":
#
#                              do_something()
#
#                    elseif req.method=="POST":
#
#                              do_something_else()
#
# GET:         包含全部HTTP GET參數的類字典對象
#
# POST:       包含全部HTTP POST參數的類字典對象
#
#              服務器收到空的POST請求的狀況也是可能發生的,也就是說,表單form經過
#              HTTP POST方法提交請求,可是表單中可能沒有數據,所以不能使用
#              if req.POST來判斷是否使用了HTTP POST 方法;應該使用  if req.method=="POST"
#
#
#
# COOKIES:     包含全部cookies的標準Python字典對象;keys和values都是字符串。
#
# FILES:      包含全部上傳文件的類字典對象;FILES中的每個Key都是<input type="file" name="" />標籤中                     name屬性的值,FILES中的每個value同時也是一個標準的python字典對象,包含下面三個Keys:
#
#             filename:      上傳文件名,用字符串表示
#             content_type:   上傳文件的Content Type
#             content:       上傳文件的原始內容
#
#
# user:       是一個django.contrib.auth.models.User對象,表明當前登錄的用戶。若是訪問用戶當前
#              沒有登錄,user將被初始化爲django.contrib.auth.models.AnonymousUser的實例。你
#              能夠經過user的is_authenticated()方法來辨別用戶是否登錄:
#              if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
#              時該屬性纔可用
#
# session:    惟一可讀寫的屬性,表明當前會話的字典對象;本身有激活Django中的session支持時該屬性纔可用。

#方法
get_full_path(),   好比:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()獲得的結果就是/index33/?name=123
req.path:/index33
full_path 拿到的含有參數  

HtppResponse 對象

HttpResponse類在django.http.HttpResponse

render 和 render_to_response 的區別是render_to_response的第一個參數不用寫request,效果都是頁面渲染

render(request,"register.html")

render_to_resonse("register.html")

這裏推薦使用render

locals()--->局部變量  將函數文件中的全部變量傳遞給模板,這裏咱們建議不要使用locals(函數中的變量名得和模板文件中的變量名一致,咱們也能夠在模板文件中直接調用局部變量request.method),最好是指定變量傳遞模板文件,好比說render(request,"register.html",{"time":t,"username":name})

redirect

redirect(「/login/」) 頁面跳轉,register.html---->return redirect("login")---->urlpattern---->view---->def login()---->login.html---->咱們能夠看到瀏覽器的URL地址也發生了變化,從register到login

template(模板)

一、模板的組成:
HTML代碼+python邏輯控制代碼

二、邏輯控制代碼的組成

2.一、變量(使用雙大括號來應用變量)

  html引用格式:{{ var_name }}

 

深度查詢(萬能的句點號)

.索引    --->列表

.key     --->字典

變量的過濾器

語法格式: {{obj|filter:param}}


   # 1  add          :   給變量加上相應的值
   #
   # 2  addslashes   :    給變量中的引號前加上斜線
   #
   # 3  capfirst     :    首字母大寫
   #
   # 4  cut          :   從字符串中移除指定的字符
   #
   # 5  date         :   格式化日期字符串
   #
   # 6  default      :   若是值是False,就替換成設置的默認值,不然就是用原本的值
   #
   # 7  default_if_none:  若是值是None,就替換成設置的默認值,不然就使用原本的值


#實例:

#value1="aBcDe"
{{ value1|upper }}<br>  字母所有大寫

#value2=5
{{ value2|add:3 }}<br>  加3

#value3='he  llo wo r ld'
{{ value3|cut:' ' }}<br> 去除指定字符串

#import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br>  時間格式化

#value5=[]
{{ value5|default:'bigbao' }}<br>   當取指定字符串的時候,沒有的狀況下給他設置一個默認值

#value6='<a href="#">跳轉</a>'

{{ value6 }}

{% autoescape off %}
  {{ value6 }}
{% endautoescape %}

{{ value6|safe }}<br>

{{ value6|striptags }}

#value7='1234'
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br>

#value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
    value9='hello I am yuan'
<h1>{{ name_list.4|default:'h  e l l o ' |upper|cut:" " }}</h1>

模板中if 和 for 循環:{% 標籤 %}

標籤的使用tag(使用大括號和百分號的組合來使用tag)

view
----------------------------------------------

def query(request):
    name_list=['bigbao','z  ho  ng','xiaohu']
    d={'name':'bigbao','age':18,'hobby':'girl'}
    return render(request,"index.html",locals())

-------------------------
html,這裏的if 能夠嵌套if
-------------------------
{% if d.age < 15 %}
    <h1> hello {{ d.name }}</h1>
{% elif d.age == 20 %}
    <h1>hello {{ d.hobby }}</h1>
{% else %}
    <h1>hello {{ d.age }}</h1>
{% endif %}
{% if %} 標籤接受and,or或者not來測試多個變量值或者否認一個給定的變量
{% if %} 標籤不容許同一標籤裏同時出現and和or,不然邏輯容易產生歧義,例以下面的標籤是不合法的:

{% if obj1 and obj2 or obj3 %} 
forloop.counter 就是一個計數器,循環的次數,從1開始,可是要是forloop.counter0 就是從0開始計數了

{% for foo in name_list %}
<h1>{{ forloop.counter }} : {{ foo }}</h1>
{% endfor %}  

還有一些其餘的標籤以及自定義標籤,看一下老師的博客

模板繼承(extend)

正常狀況下,咱們有一部分樣式是想保持不變的。這個時候各個頁面都要繼承這個基礎樣式,有特殊需求的能夠在本身的頁面進行修改。好比說下面這個例子

----------------------------------url.py-----------------------------------------------
    path('backend/',views.backend),
    path('teacher/',views.teacher,name="teacher"),
    path('student/',views.student,name="student"),
---------------------------------views.py---------------------------------------------
def backend(request):
    return render(request,'backend.html')

def teacher(request):
    teacher_list=['teacher_1','teacher_2','teacher_3']
    return render(request,'teacher.html',locals())

def student(request):
    student_list=['student_A','student_B','student_C']
    return render(request,'student.html',{'student':student_list})
--------------------------base.html------------------------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
 <title> {% block style %} {% endblock %} </title>
    <script src="/static/jquery-3.1.1.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .nav{
            line-height: 40px;
            width: 100%;
            background-color: #2459a2;
            color: white;
            font-size: 20px;
            text-align: center;
        }

        .left{
            float: left;
            width:20%;
            min-height: 600px;
            overflow: auto;
            background-color: #ededed;
        }
        .manager{
            text-align: center;
            padding: 20px 0;
            margin: 15px 0;
            font-size: 18px;

        }
        a {
            text-decoration: none;
        }

        .content{
            float: left;
            width: 70%;
            min-height: 600px;
            text-align: center;
        }
        h3{
            color: red;
            font-size: 50px;
        }

    </style>
</head>
<body>
<div class="outer">
    <div class="nav">標題</div>
    <div class="left">
        <div class="teacher manager"><a href="/teacher/">老師管理</a></div>
        <div class="student manager"><a href="/student/">學生管理</a></div>
        <div class="course manager"><a href="">課程管理</a></div>
        <div class="classes manager"><a href="">班級管理</a></div>
    </div>
 <div class="content"> {% block content %} {% endblock %} </div>
</div>

</body>
</html>

-----------------------------------backend.html-------------------------------------
{% extends "base.html" %}

{% block content %}
    <h1> Welcome To BigBaoOps</h1>
{% endblock %}


---------------------------------teacher.html----------------------------------------

{% extends "base.html" %} {% block style %} Teacher Page {% endblock %} {% block content %} {% for foo in teacher_list %} <h2>{{ foo }}</h2> {% endfor %} {% endblock %}

---------------------------------teacher.html-----------------------------------------
{% extends "base.html" %}

{% block style %}
    Student Page
{% endblock %}

{% block content %}
    {% for foo in student %}
    <h3>{{ foo }}</h3>
    {% endfor %}

{% endblock %}  

 

這裏咱們在base.html 上指定的標籤上添加一個block,好比這裏我給了個人title和個人content分別設置了block

而後在咱們的子模塊上的第一行永遠是

{% extends "base.html" %} 

 而後對本身的 block 作格式設置以及文字添加

注意:

 <1>若是在模板中使用 {% extends %} ,必須保證其爲模板中的第一個模板標記。 不然,模板繼承將不起做用。

 <2>通常來講,基礎模板中的 {% block %} 標籤越多越好。 記住,子模板沒必要定義父模板中全部的代碼塊,所以
    你能夠用合理的缺省值對一些代碼塊進行填充,而後只對子模板所需的代碼塊進行(重)定義。 俗話說,鉤子越
    多越好。

 <3>若是發覺本身在多個模板之間拷貝代碼,你應該考慮將該代碼段放置到父模板的某個 {% block %} 中。
    若是你須要訪問父模板中的塊的內容,使用 {{ block.super }}這個標籤吧,這一個魔法變量將會表現出父模
    板中的內容。 若是隻想在上級代碼塊基礎上添加內容,而不是所有重載,該變量就顯得很是有用了。

 <4>不容許在同一個模板中定義多個同名的 {% block %} 。 存在這樣的限制是由於block 標籤的工做方式是雙向的。
    也就是說,block 標籤不只挖了一個要填的坑,也定義了在父模板中這個坑所填充的內容。若是模板中出現了兩個
    相同名稱的 {% block %} 標籤,父模板將無從得知要使用哪一個塊的內容。



include 擴展模塊
在講解了模板加載機制以後,咱們再介紹一個利用該機制的內建模板標籤: {% include %} 。該標籤容許在(模板中)包含其它的模板的內容。 標籤的參數是所要包含的模板名稱,
能夠是一個變量,也能夠是用單/雙引號硬編碼的字符串。 每當在多個模板中出現相同的代碼時,就應該考慮是否要使用 {% include %} 來減小重複。
好比說咱們如今有一個test.html ,可是咱們想在 student.html 裏面加載test.html 的內容
那麼咱們就在student.html 作以下設置
{% load staticfiles %}
而後在你想要的位置引入test.html 的內容的地方作以下設置
{% include "test.html" %}
相關文章
相關標籤/搜索