1. 程式人生 > 實用技巧 >django基礎01

django基礎01

建立專案

  1. 通過命令列的方式:首先要進入到安裝了django的虛擬環境中。然後執行命令:

    django-admin startproject [專案的名稱]
    

    這樣就可以在當前目錄下建立一個專案了。

  2. 通過pycharm的方式:檔案->新建專案->選擇django。然後指定專案所在的路徑,以及Python直譯器,再點選Create就可以建立專案了。

執行專案

  1. 終端:進入到專案資料夾中,然後執行以下命令即可執行:

    python manage.py runserver
    
  2. pycharm:直接點選右上角的綠色三角箭頭按鈕就可以了。注意:用pycharm執行專案,要避免一個專案執行多次。

    。在專案配置中,把“只用單一例項”那個選項勾選上,避免以上的問題。

改變埠號

  1. 在終端:執行的時候加上一個埠號就可以了。命令為:python manage.py runserver 9000
  2. 在pycharm中:右上角->專案配置->port。改成你想要的埠號,重新執行。

讓同區域網中的其他電腦訪問本機的專案

  1. 讓專案執行到額時候,host為0.0.0.0。

    • 在終端,使用命令:python manage.py runserver 0.0.0.0:8000
    • 在pycharm,右上角->專案配置->host。改成0.0.0.0
  2. settings.py檔案中,配置ALLOWED_HOSTS

    ,將本機的ip地址新增進去。示例程式碼如下:

    ALLOWED_HOSTS = ['192.168.0.103']
    

    注意:要關閉自己電腦的防火牆才行。

專案結構分析

  1. manange.py:以後和專案互動基本上都是基於這個檔案。一般都是在終端輸入python manage.py [子命令]。可以輸入python manage.py help看下能做什麼事情。除非你知道你自己在做什麼,一般情況下不應該編輯這個檔案。
  2. settings.py:儲存專案所有的配置資訊。
  3. urls.py:用來做url與檢視函式對映的。以後來了一個請求,就會從這個檔案中找到匹配的檢視函式。
  4. wsig.py:專門用來做部署的。不需要修改。

django推薦的專案規範

按照功能或者模組進行分層,分成一個個app。所有和某個模組相關的檢視都寫在對應的app的views.py中,並且模型和其他的也是類似。然後django已經提供了一個比較方便建立app的命令叫做python manage.py startapp [app的名稱]。把所有的程式碼寫在各自的app中。

DEBUG模式

  1. 如果開啟了DEBUG模式,那麼以後我們修改了Django專案的程式碼,然後按下ctrl+s,那麼Django就會自動的給我們重啟專案,不需要手動重啟。
  2. 如果開啟了DEBUG模式,那麼以後Django專案中的程式碼出現bug了,那麼在瀏覽器中和控制檯會打印出錯資訊。
  3. 在生產環境中,禁止開啟DEBUG模式,不然有很大的安全隱患。
  4. 如果將DEBUG設定為False,那麼必須要設定ALLOWED_HOSTS.

ALLOWED_HOSTS

這個變數是用來設定以後別人只能通過這個變數中的ip地址或者域名來進行訪問。

前端引數傳遞

  • 採用url路徑中使用PATH的方式傳遞引數,採用<int:id>的方式來傳遞,一定要在檢視函式中的引數中對引數進行接收,否則報錯

  • 採用查詢字串的方式,在url後面加上?xxx=xxx的方式來傳遞引數,後端接收引數使用request.GET.get("xxx")的方式來獲取引數

  • 使用表單的方式來傳遞,在後端使用request.POST.get(“xxx”)來獲取前端傳遞的引數

  • 使用json的方式進行傳遞,在後端使用data = request.body.decode("utf-8")json.loads(data)來獲取json格式的資料

url轉換器

使用格式/<int:id>/的格式來使用轉換器,如果不指定轉換器型別,預設使用的是str轉換器

django預設的轉換器

DEFAULT_CONVERTERS = {
    'int': IntConverter(),
    'path': PathConverter(),
    'slug': SlugConverter(),
    'str': StringConverter(),
    'uuid': UUIDConverter(),
}
class IntConverter:
    regex = '[0-9]+'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return str(value)
def register_converter(converter, type_name):
    REGISTERED_CONVERTERS[type_name] = converter()
    get_converters.cache_clear()
  • 自定義url轉換器

參照官方的轉換器寫法定義一個轉換器類,將這個轉換器類註冊到DEFAULT_CONVERTERS中
1、定義一個類,直接繼承自object就可以
2、在類中定義一個屬性regex,這個屬性是用來限制url轉換器規則的正則表示式。
3、實現to_python(self,value)方法,這個方法是將url中的值轉換下,然後傳給檢視函式的。
4、實現to_url(self,value)方法,這個方法是在做url反轉的時候,將傳進來的引數轉換後拼接成一個正確的url。
5、將定義好的轉換器,使用'django.urls.converters.register_converter'方法註冊到django中。

from django.urls import register_converter


class CategoryConverter(object):
    regex = r'\w+|(\w+\+\w+)+'

    def to_python(self, value):
        # 將url裡的'python+django+pandas'轉換成:['python', 'django', 'pandas']傳給檢視函式
        result = value.split('+')
        return result

    def to_url(self, value):
        if isinstance(value, list):
            # 將檢視函式裡的['python', 'django', 'pandas']轉換成'python+django+pandas'傳給URL
            result = '+'.join(value)
            return result
        else:
            raise RuntimeError('轉換url的時候,分類引數必須為列表')

# register_converter(上面自己定義的類名,自定義的型別名(在urls.py檔案中使用))
register_converter(CategoryConverter, 'cate')

在app根目錄下的__init__.py中新增:

from . import converters

在urls.py中使用即可,如:

path('article/<cate:classify>',views.article_classify_list,name='article_classify'),

urls模組化

如果專案變得越來越大。那麼url會變得越來越多。如果都放在主urls.py檔案中,那麼將不太好管理。因此我們可以將每個app自己的urls放到自己的app中進行管理。一般我們會在app中新建一個urls.py檔案用來儲存所有和這個app相關的子url。
需要注意的地方:

  1. 應該使用include函式包含子urls.py,並且這個urls.py的路徑是相對於專案的路徑。示例程式碼如下:
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('book',include('book.urls'))
    ]
    
  2. appurls.py中,所有的url匹配也要放在一個叫做urlpatterns的變數中,否則找不到。
  3. url是會根據主urls.py和app中的urls.py進行拼接的,因此注意不要多加斜槓。

include函式的用法

  1. include(module,namespace=None):
    • module:子url的模組字串。
    • namespace:例項名稱空間。這個地方需要注意一點。如果指定例項名稱空間,那麼前提必須要先指定應用名稱空間。也就是在子urls.py中新增app_name變數。
  2. include((pattern_list, app_namespace), namespace=None):include函式的第一個引數既可以為一個字串,也可以為一個元組,如果是元組,那麼元組的第一個引數是子urls.py模組的字串,元組的第二個引數是應用名稱空間。也就是說,應用名稱空間既可以在子urls.py中通過app_name指定,也可以在include函式中指定。
  3. include(pattern_list):pattern_list是一個列表。這個列表中裝的是path或者re_path函式。例項程式碼如下:
    path('movie/',include([
        path('',views.movie),
        path('list/',views.movie_list),
    ]))
    

url反轉和重定向

需要用到i的函式from django.shortcuts import redirect,resolve_url

url反轉需要在url定義的時候給url取個名字,在urls.py記得使用app_name指定應用名稱空間,以後在做反轉的時候front:index來反轉index對應的的url

重定向直接呼叫redirect(args) 引數可以是一個模型,或者是url字串或者檢視函式的名字

reverse用法

  1. 如果在反轉url的時候,需要新增引數,那麼可以傳遞kwargs引數到revers函式中。示例程式碼如下:

    detail_url = reverse('detail',kwargs={"article_id":1,'page':2})
    
  2. 如果想要新增查詢字串的引數,則必須手動的進行拼接。示例程式碼如下:

    login_url = reverse('login') + "?next=/"
    

偏函式

在Python中的functools中partial來實現 ,這個函式的作用是給有固定引數的函式一個簡單的封裝

def _index(arg1,arg2,arg3=None):
    print(arg1)
    print(arg2)
    print(arg3)

from functools import partial

index = partial(_index,2,arg3=4)
index(3)
>>>
2
3
4

URL對映的時候指定預設引數

使用path或者是re_path的後,在route中都可以包含引數,而有時候想指定預設的引數,這時候可以通過以下方式來完成。示例程式碼如下:

from django.urls import path

from . import views

urlpatterns = [
    path('blog/', views.page),
    path('blog/page<int:num>/', views.page),
]

# View (in blog/views.py)
def page(request, num=1):
    # Output the appropriate page of blog entries, according to num.
    ...

當在訪問blog/的時候,因為沒有傳遞num引數,所以會匹配到第一個url,這時候就執行view.page這個檢視函式,而在page函式中,又有num=1這個預設引數。因此這時候就可以不用傳遞引數。而如果訪問blog/1的時候,因為在傳遞引數的時候傳遞了num,因此會匹配到第二個url,這時候也會執行views.page,然後把傳遞進來的引數傳給page函式中的num。

re_path用法

  1. re_path和path的作用都是一樣的。只不過re_path是在寫url的時候可以用正則表示式,功能更加強大。
  2. 寫正則表示式都推薦使用原生字串。也就是以r開頭的字串。
  3. 在正則表示式中定義變數,需要使用圓括號括起來。這個引數是有名字的,那麼需要使用?P<引數的名字>。然後在後面新增正則表示式的規則。示例程式碼如下:
    from django.urls import re_path
    from . import views
    
    urlpatterns = [
        # r"":代表的是原生字串(raw)
        re_path(r'^$',views.article),
        # /article/list/<year>/
        re_path(r"^list/(?P<year>\d{4})/$",views.article_list),
        re_path(r"^list/(?P<month>\d{2})/$",views.article_list_month)
    ]
    
  4. 如果不是特別要求。直接使用path就夠了,省的把程式碼搞的很麻煩(因為正則表示式其實是非常晦澀的,特別是一些比較複雜的正則表示式,今天寫的明天可能就不記得了)。除非是url中確實是需要使用正則表示式來解決才使用re_path

為什麼需要url命名?

因為url是經常變化的。如果在程式碼中寫死可能會經常改程式碼。給url取個名字,以後使用url的時候就使用他的名字進行反轉就可以了,就不需要寫死url了。

如何給一個url指定名稱?

path函式中,傳遞一個name引數就可以指定。示例程式碼如下:

urlpatterns = [
    path('',views.index,name='index'),
    path('login/',views.login,name='login')
]

應用名稱空間

在多個app之間,有可能產生同名的url。這時候為了避免反轉url的時候產生混淆,可以使用應用名稱空間,來做區分。定義應用名稱空間非常簡單,只要在appurls.py中定義一個叫做app_name的變數,來指定這個應用的名稱空間即可。示例程式碼如下:

# 應用名稱空間
app_name = 'front'

urlpatterns = [
    path('',views.index,name='index'),
    path('login/',views.login,name='login')
]

以後在做反轉的時候就可以使用應用名稱空間:url名稱的方式進行反轉。示例程式碼如下:

login_url = reverse('front:login')

應用(app)名稱空間和例項名稱空間

一個app,可以建立多個例項。可以使用多個url對映同一個app。所以這就會產生一個問題。以後在做反轉的時候,如果使用應用名稱空間,那麼就會發生混淆。為了避免這個問題。我們可以使用例項名稱空間。例項名稱空間也是非常簡單,只要在include函式中傳遞一個namespace變數即可。示例程式碼如下:

urlpatterns = [
    path('',include('front.urls')),
    # 同一個app下有兩個例項
    path('cms1/',include('cms.urls',namespace='cms1')),
    path('cms2/',include('cms.urls',namespace='cms2')),
]

以後在做反轉的時候,就可以根據例項名稱空間來指定具體的url。示例程式碼如下:

def index(request):
    username = request.GET.get("username")
    if username:
        return HttpResponse('CMS首頁')
    else:
        # 獲取當前的名稱空間
        current_namespace = request.resolver_match.namespace
        return redirect(reverse("%s:login"%current_namespace))

檢視函式

  1. 檢視函式的第一個引數必須是request。這個引數絕對不能少。
  2. 檢視函式的返回值必須是django.http.response.HttpResponseBase的子類的物件。