Django基礎教程之初體驗

SilenceHL 發表於 2021-04-04

宣告:以下內容均為我個人的理解,如果發現錯誤或者疑問可以聯絡我共同探討

簡介

在Django2.0以後,Django已經不支援python2.7,所以我們需要一個python3的系統環境,這裡一python3.6為例

安裝Django

三種方式安裝

pip安裝

  • 一般情況下安裝python後會幫你安裝好pip,當你沒安裝時使用這個連結安裝,記得更新到最新版本

  • 安裝並使用virtualenv

  • 在建立好並啟用的虛擬環境中輸入一下命令

    $ pip install Django

通過第三方軟體包

管理系統整合的Django

安裝開發版本

  • 安裝好git

  • 輸入一下命令下載Django

    $ git clone https://github.com/django/django.git
  • 安裝並使用virtualenv

  • 在建立好並啟用的虛擬環境中輸入一下命令

    $ pip install -e django/

安裝好Django後可以通過一下命令檢視當前Django版本

$ python -m django --version

Django初體驗

安裝並使用virtualenv

詳細過程見這個連結

建立Django專案

在專案存放目錄開啟命令列執行一下命令:

$ django-admin startproject mysite

這句話執行過後會在當前目錄生成一個名字為mysite的Django專案,目錄結構為下

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

這些目錄和檔案的作用:

  • mysite/目錄:存放專案的容器,他的名字不重要可以更換為你喜歡的任何名字

  • manage.py:Django專案的啟動檔案,他可以讓你通過各種方式管理Django專案。

  • mysite/mysite/目錄:專案目錄,裡面存放專案相關的檔案

  • mysite/mysite/settings.py:Django專案的配置檔案

  • mysite/mysite/urls.py:Django專案的url宣告檔案,他將url對應相關的app的檢視

  • mysite/mysite/wsgi.py:Django專案wsgi伺服器的入口

  • 當輸入以下命令,並進入瀏覽器輸入:http://127.0.0.1:8000/看到Django啟動成功

    $ python manage.py runserver

    這裡能啟動成功是因為Django自帶一個簡易的伺服器(用純 Python 寫的輕量級的 Web 伺服器)。他能幫助我們快速開發。

建立一個應用

  • 將當前目錄切換到manage.py所在的目錄,輸入下面的命令建立一個應用:

    $ python manage.py startapp demo

    該應用的目錄結構大致如下

    demo/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py

    這些目錄和檔案的作用:

    • admin.py:管理admin後臺相關資料庫模型
    • apps.py:該應用的相關配置
    • migrations/資料夾及其內容:資料庫遷移相關的資料夾,裡面存放著遷移版本,遷移資訊等
    • models.py:編寫模型類的檔案
    • tests.py:用於測試的檔案
    • view.py:編寫檢視的檔案

    我們還要在專案配置檔案中註冊該app,開啟settings.py檔案,找到INSTALLED_APPS,在列表的最後新增demoapp

    mysite/settings.py
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # 註冊demo
        'demo.apps.DemoConfig'
    ]
    

編寫第一個檢視

檢視在應用的views.py中編寫

  demo/views.py

  from django.http import HttpResponse

  def index(request):
      return HttpResponse("Hello, world!")

為了能看到效果我們還需要配置一下url,在demo目錄下建立一個urls.py,並輸入一下程式碼

  /demo/urls.py

  from django.urls import path
  from . import views

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

更改專案url,通過修改專案urls.py檔案修改路由

  /mysite/urls.py

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

  urlpatterns = [
      path('demo/', include('demo.urls')),
      path('admin/', admin.site.urls),
  ]

這裡include是將demo/的路由轉發到demo應用的urls.py裡。每當 Django 遇到 include時,它會截斷與此項匹配的 URL 的部分,並將剩餘的字串傳送到 對應urls.py以供進一步處理。

path有五個引數:route、view、kwargs、name、Pattern,其中route、view是必須傳入的引數

  • route:匹配url的準則(類似於正規表示式)。當Django響應一個請求時,他會從urlpatterns的第一項開始,按順序依次匹配,知道找到匹配的項
  • view:目標檢視函式。當route找到匹配的項後,會呼叫當前的檢視函式,並傳入一個HttpRequest物件作為第一個引數,route中的引數一關鍵字引數的形式傳入
  • kwargs:關鍵字引數。任意個關鍵字引數可以作為一個字典傳遞給目標檢視函式。
  • name:為url取的名字。他可以使Django在任意地方引用他
  • Pattern:匹配模式

現在可以啟動Django程式來看是否正常工作

資料庫

建立資料庫

進入mysql並建立一個test資料庫,字元設定為utf8

$ mysql -uroot -p
mysql> create database test charset=utf8;
Query OK, 1 row affected (0.00 sec)

資料庫配置

首先我們需要配置mysite/setting.py中的資料庫DATABASES選項,Django預設是sqlite資料庫,如果個人專案不大的情況下可以使用這個,也可以使用自己熟悉的資料庫,Django不僅支援sqlite,postgresql,mysql,或oracle,還支援很多有第三方外掛的資料庫,我使用mysql資料庫

/mysite/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        # 資料庫名
        'NAME': 'test', 
        # 使用者名稱
        'USER': 'root', 
        # 密碼
        'PASSWORD': 'mysql'
        # 主機,預設為localhost
        'HOST': ''
        # 埠號,預設為3306
        'PORT': ''
    }
}

資料庫遷移

因為Django自帶應用已經為我們編寫了一些資料模型,即時我們不編寫任何模型也可以直接使用資料庫遷移命令進行遷移

$ python manage.py migrate

會看到初始化了很多使用者、許可權相關的表

建立一個管理員賬號,依次輸入使用者名稱、郵箱、密碼、確認密碼,建議密碼設定複雜點

$ python manage.py createsuperuser
使用者名稱 (leave blank to use '02'): admin
電子郵件地址: 1@gmail.com
Password:
Password (again):
密碼跟 使用者名稱 太相似了。
密碼長度太短。密碼必須包含至少 8 個字元。
這個密碼太常見了。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

接下來啟動專案,並在瀏覽器中輸入http://127.0.0.1:8000/admin,進入後臺管理介面

Django基礎教程之初體驗

輸入賬號密碼,點選登入即可

Django基礎教程之初體驗

資料庫遷移,需要三步

  • 編寫models.py檔案,改變模型。

  • 執行 python manage.py makemigrations為模型的改變生成遷移檔案。

  • 執行 python manage.py migrate 來應用資料庫遷移。

建立一個圖書模型

在demo應用下建立一個圖書模型

/demo/models.py

from django.db import models

class Books(models.Model):
    # 書名
    book_name = models.CharField(max_length=200)
    # 作者
    author = models.CharField(max_length=50)

建立的模型有兩個欄位,書名和作者,使用了字元型別,增加了長度限制(注意在使用CharField時必須要新增max_length限制

建立遷移模型並生成遷移檔案

$ python manage.py makemigrations demo
Migrations for 'demo':
  demo\migrations\0001_initial.py
    - Create model Books

會出現建立了Books這個模型,在demo應用的migrations資料夾下會多一個0001_initila.py的遷移檔案,可以使用python manage.py sqlmigrate demo 0001可以檢視這次資料庫遷移的操作與具體的SQL語句

$ python manage.py sqlmigrate demo 0001
BEGIN;
--
-- Create model Books
--
CREATE TABLE `demo_books` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `book_name` varchar(200) NOT NULL, `auhtor` varchar(50) NOT NULL);
COMMIT;

需要注意一下幾點:

  • 輸出的內容與使用的資料庫有關。
  • 資料庫的表名預設是“應用名_模型名的小寫”,也可以自定義表名。
  • 主鍵會預設自動建立,也可以自定義主鍵。
  • Django會為使用的資料庫定製相關SQL語句,例如主鍵:integer AUTO_INCREMENT NOT NULL PRIMARY KEY,varchar:NOT NULL
  • sqlmigrate命令並沒有真正執行遷移命令,他只是將遷移命令執行的流程輸出到螢幕上,供你檢視

執行check命令對專案做檢查

$ python manage.py check
System check identified no issues (0 silenced).

沒有問題後執行遷移命令

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, demo, sessions
Running migrations:
  Applying demo.0001_initial... OK

看到以上內容即完成了資料庫遷移

通過Python命令列嘗試

$ python manage.py shell
>>> from demo.models import Books
>>> ggzh = Books(book_name="矽谷之火",author="邁克爾.斯韋因")
>>> ggzh.save()
>>> ggzh.id
1
>>> ggzh.book_name
'矽谷之火'
>>> ggzh.author
'邁克爾.斯韋因'
>>> Books.objects.all()
<QuerySet [<Books: Books object (1)>]>

這裡我們看到<QuerySet [<Books: Books object (1)>]>這個並不能讓我們知道這個物件的細節,通過修改Books模型來修復這個問題

/demo/models.py

class Books(models.Model):
    # 書名
    book_name = models.CharField(max_length=200)
    # 作者
    author = models.CharField(max_length=50)

    def __str__(self):
        return self.book_name

修改完成後重新進入互動終端,再次查詢就可以顯示書名了,這裡可以自己定義想顯示的欄位或內容

$ python manage.py shell
>>> from demo.models import Books
>>> Books.objects.all()
<QuerySet [<Books: 矽谷之火>]>

再新增一本書,聚合函式

>>> qbsz = Books(book_name="史蒂夫*賈伯斯傳",author="沃爾特·艾薩克森")
>>> qbsz.save()
>>> Books.objects.all()
<QuerySet [<Books: 矽谷之火>, <Books: 史蒂夫*賈伯斯傳>]>
>>> Books.objects.count()
2
>>> Books.objects.filter(book_name="矽谷之火")
<QuerySet [<Books: 矽谷之火>]>

接下來我們將Books模型新增到admin管理,通過register方法,將Books交給admin管理

/demo/admin

from django.contrib import admin

from .models import Books

admin.site.register(Books)

重新執行專案,在位址列輸入:http://127.0.0.1:8000/admin/,輸入賬號密碼登入即可檢視到這個模型

Django基礎教程之初體驗

點進去可以檢視該模型的資料,右上角可以新增,動作可以刪除,點圖書名可以看到更多細節

後臺管理圖書

檢視與模板

在models.py中新增一個圖書模型

/demo/models.py

from django.db import models


class Books(models.Model):
    # 書名
    name = models.CharField('書名', max_length=200)
    # 作者
    author = models.CharField('作者', max_length=50)
    publish_house = models.CharField('出版社', max_length=50)
    publish_date = models.CharField('出版日期', max_length=50)
    price = models.IntegerField('價格')
    synopsis = models.TextField('簡介')

    def __str__(self):
        return self.name

在admin.py中註冊Books

遷移資料庫

在Django後臺中新增圖書資料

在應用的views.py中編寫一個展示圖書的檢視

/demo/views.py

from django.http import HttpResponse
from .models import Books


def book_list(request):
    book_list = Books.objects.all()
    books = {book.name : book.id for book in book_list}
    return render(request, 'index.html', context={'books': books})

通過模板渲染

在templates目錄下新建一個index.html檔案

/tempaltes/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div>圖書管理系統:</div>
<ul>
</ul>
</body>
</html>

在專案的urls.py檔案中新增一個關於圖書的路由

/mysite/urls.py

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

from demo import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/', include('demo.urls')),
]

在demo目錄中新建一個urls.py檔案,並新增一個路由

/demo/urls.py

from django.urls import path

from . import views

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

啟動專案,訪問:127.0.0.1:8000/book/

圖書列表頁完成了,接下來編寫圖書詳情頁

在demo專案中的urls.py檔案中新增一個詳情頁的路由

/demo/urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('', views.book_list, name='index'),
    path('<int:id>/', views.detail, name='detail'),
]

在demo專案中的views.py檔案中編寫詳情頁相關檢視函式

/demo/views.py

def detail(request, id):
    book = Books.objects.filter(id=id).all()[0]
    content = {
        "name": book.name,
        "author": book.author,
        'publish_house': book.publish_house,
        'publish_date': book.publish_date,
        'price': book.price,
        'synopsis': book.synopsis
    }
    return render(request, 'detail.html', context=content)

在templates資料夾裡新建一個detail.html檔案,並寫入一下程式碼

/templates/detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <td>書名</td>
        <td>作者</td>
        <td>出版社</td>
        <td>出版日期</td>
        <td>價格</td>
        <td>簡介</td>
    </tr>
    <tr>
        <td>{{ name }}</td>
        <td>{{ author }}</td>
        <td>{{ publish_house }}</td>
        <td>{{ publish_date }}</td>
        <td>{{ price }}</td>
        <td>{{ synopsis }}</td>
    </tr>
</table>

</body>
</html>

啟動專案,訪問:http://127.0.0.1:8000/book/,點選其中一個圖書就可以看到詳情頁,或者直接選擇一個id訪問詳情頁,這時候就會出現一個問題,當訪問一個不存在的id時就會出錯,我們需要定製一下錯誤頁面,修改detail檢視函式。

/demo/views.py
from django.http import Http404
...
def detail(request, id):
    books = Books.objects.filter(id=id).all()
    if len(books):
        book = books[0]
        content = {
            "name": book.name,
            "author": book.author,
            'publish_house': book.publish_house,
            'publish_date': book.publish_date,
            'price': book.price,
            'synopsis': book.synopsis
        }
        return render(request, 'detail.html', context=content)
    else:
        raise Http404("圖書不存在")

這裡呼叫的是Django自帶的404錯誤頁面,我們需要返回錯誤說明

本作品採用《CC 協議》,轉載必須註明作者和本文連結