Python Django 學習紀錄(四) 資料庫及後台管理

 

 

一、Django 與資料庫:

Django 預設 以Model 方式操作資料庫,以 class 類別建立 Model,再透過 Model 操作資料庫和資料表,之後要更改資料庫系統,只要更改 Model 的定義即可。

1.使用 Django 資料庫:

  1. 使用 Django 資料庫要先進行以下步驟:
  2. 在 <model.py> 檔中定義class類別,每個類別相當於一個資料表
  3. 在 class 類別中定義變數,每一個變數相當於一個資料表欄位
  4. 以「 python manage.py makemigrations app名稱」或 「 python manage.py makemigrations 」來建立資料庫和 Django的中介檔
  5. 以 「 python manage.py migrate」同步更新資料庫內容
  6. 在 Python程式中存取資料庫

 

1.定義資料模型:

接下來將直接專案實作:

1.建立一個名為students的專案,接著建立名為studentsapp的app,在<settings.py>註冊App

  創建templates目錄、static目錄、migration資料檔,利用migrate將模型與資料庫同步。

22.JPG

2.記得要在 <setting.py>進行整個專案的環境設定,前面幾個專案已經設定過許多次,這裡將不再說明。

3.接著在 <urls.py>定義以下自訂函式:

先將還不會用到的路徑註解掉,之後再陸續打開,以免之後設定會產生錯誤 

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

urlpatterns = [
    path('admin/', admin.site.urls),
    # path('listone/',views.listone),
    # path('listall',views.listall),
    # path('',views.index),
    # path('index',views.index),
]

 

(1)建立資料模型

請開啟 studentsapp專案下的 <models.py> 檔,該檔預設已經import model套件。

建立 students 類別,建立的類別必須以「class student(model.Model)」繼承model.Model,然後在student類別建立欄位:

from django.db import models


class student(models.Model):
    cName = models.CharField(max_length=20, null=False) #建立字串型別的欄位,最大長度為20字元,欄位不可空白
    cSex = models.CharField(max_length=2, default='M', null=False) #default='M',設定預設值為'M'
    cBirthday = models.DateField(null=False)
    cEmail = models.EmailField(max_length=100,blank=True, default='')#blank=True 欄位可空白
    cPhone = models.CharField(max_length=50,blank=True, default='')
    cAddr = models.CharField(max_length=255,blank=True, default='')

    #每一筆資料在管理介面顯示的內容以下列程式定義
    def __str__(self):
        return self.cName #表示顯示cName欄位


(2)model.Model 常用的欄位、欄位的屬性

前面範例已經有介紹幾個,還有許多的欄位請至官網深入了解  點此連結 

(3)建立 migration 資料檔

資料庫模型建立完成後,必須將建立資料表的架構和版本記錄下來,以利以後的追蹤。

如果專案伺服器是啟動中的,請按 CTRL+C 關閉伺服器,回到students 目錄,並以「python manage.py  makemigrations」更新migrations目錄。

接著以「 python manage.py migrate」進行migrate,migrate會根據migrations紀錄將模型同步到資料庫。

24.JPG

 

 

二、admin 後台管理與 ModelAdmin 類別:

Migrate 成功後會在專案跟目錄下建立 <db.sqlite3> 資料庫,利用 admin 可以管理後台,新增、修改或刪除。

1. admin 後台管理

請開啟 studentsapp 目錄底下的 <admin.py> 並寫入以下程序:

from django.contrib import admin

#因為student定義在models.py,所以需要import來加入該套件
from studentsapp.models import student

#下面會以register的方式,將建立的資料模型向admin註冊
admin.site.register(student)

 

記得要儲存文件,接下來先關閉server,要建立管理者帳號密碼來登入admin

這邊帳號先以admin,信箱設為admin@admin.com,密碼設為aa000000(不能設為全數字)

25.JPG

創建完後就可以再次啟動伺服器,輸入「127.0.0.1:8000/admin」就會開啟admin登入畫面

26.JPG

登入之後就會看到之前註冊的資料表students 

27.JPG

點選資料表後面的新增,即可進入資料輸入的頁面

28.JPG

1新增後資料會以cName欄位顯示,因為之前在<Model.py>中做過設定(忘記的話可以往回看)

29.JPG

點選右上的新增可以繼續新增多筆資料,這邊又新增了兩筆資料,最後顯示如下:

30.JPG

2.定義 ModelAdmin 類別

在 Admin 中可以設定顯示多個類別,也可以依據指定欄位過濾資料或搜尋與排序

(1)顯示多個欄位

要在 Admin 中顯示多個欄位 要在 <admin.py> 中定義 ModelAdmin 類別,再以list_display 定義顯示的欄位,最後透過 register 的方式註冊

這邊有三種方式來顯示欄位:

第一種方式,直接 register 註冊資料表,沒有加入 ModelAdmin 類別

第二種方式,加入ModelAdmin 類別,定義顯示欄位

第三種方式,加入ModelAdmin 類別,定義顯示欄位、欄位過濾資料、搜尋和排序

依據想要採用的方式,拿掉或加上註解,這邊是採用第三種方式來顯示

from django.contrib import admin

#因為student定義在models.py,所以需要import來加入該套件
from studentsapp.models import student

#第一種方式:直接以register的方式,將建立的資料模型向admin註冊
# admin.site.register(student)

#第二種方式:加入ModelAdmin 類別,定義顯示欄位
# class studentAdmin(admin.ModelAdmin):
#     list_display=('id','cName','cSex','cBirthday','cEmail','cPhone','cPhone','cAddr')
# admin.site.register(student,studentAdmin)


#第三種方式:加入ModelAdmin 類別,定義顯示欄位、欄位過濾資料、搜尋和排序
class studentAdmin(admin.ModelAdmin):
    list_display=('id','cName','cSex','cBirthday','cEmail','cPhone','cAddr')
    list_filter=('cName','cSex')
    search_fields=('cName',)
    ordering=('id',)
admin.site.register(student,studentAdmin)


這邊講解一下第三種方法的程式碼:

  1. 資料過濾:list_filter可以建立過濾的欄位。必須使用串列或元組,會在右方顯示。
  2. 依據欄位搜尋:search_fields 可以依據指定的欄位搜尋,必須使用串列或元組,會在上方出現文字方塊以供搜尋(依據指定的欄位)。
  3. 排序:ordering 可以依據指定的欄位排序,必須使用串列或元組,加上「-」可以遞減排序。例如 ordering=('-id')。

以下是顯示出來的結果:

31.JPG

 

三、資料庫查詢:

利用 models 模組的 objects.get() 和 objects.all() 方法可以讀取資料

1. get() 方法

get()方法可以取得一筆資料,語法:

資料表.objects.get(查詢條件)

 

objects.get() 查詢成功會傳回1筆資料,若回傳是多筆資料或是資料不存在,都會產生錯誤,因此通常會做例外處理。

範例1. 以Template樣版顯示資料

首先請打開studentsapp裡的<view.py>寫一個名為listone的自訂函數

會先做try/except 的例外處理,如果try成功的話,則讀取cName欄位的'ivan'那列的所有資料,且將資料儲存在unit變數

from django.shortcuts import render
from studentsapp.models import student

def listone(request):
    try:
        unit = student.objects.get(cName="ivan") #讀取第一筆資料
    except:
        errormessage = "(讀取錯誤!)"
    return render(request,'listone.html',locals())

接著在templates目錄中創建一個<listone.html>模版

  1. 若try失敗就會顯示except的內容 {{errormessage}}
  2. {{unit.id}}顯示自動編號的 id 欄位,其餘的也是如此
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>顯示第一筆資料</title>
</head>
<body>
    <h2>顯示 student資料表一筆資料 {{errormessage}}</h2>
    編號: {{unit.id}}  <br  />
    姓名: {{unit.cName}}  <br  />
    性別: {{unit.cSex}}  <br  />
    生日: {{unit.cBirthday}}  <br  />
    郵件帳號: {{unit.cEmail}}  <br  />
    電話: {{unit.cPhone}}  <br  />
    地址: {{unit.cAddr}}  <br  />
</body>
</html>

最後記得在<urls.py>新增listone的url路徑(或是去掉之前的註解)

最後網頁執行結果如下:

32.JPG

 

2. objects.all() 方法

objects.all() 方法可以讀取資料表中的每一筆資料,語法:

資料表.objects.all

也可以將資料以「.order_by("欄位")」依據指定的欄位做排序,預設為遞增,加上「-」則是遞減排序。

範例2. 以Template樣版顯示全部資料

請打開studentsapp裡的<view.py>寫一個名為listall的自訂函數

讀取id欄位的的所有資料,並且使用「-」的方式來遞減排序,最後將資料儲存在students變數

def listall(request):

    students = student.objects.all().order_by('-id') #依據id欄位遞減排序顯示所有資料
    return render(request,'listall.html',locals())

 

接著在templates目錄中創建一個<listall.html>模版

  1. 使用for迴圈將students裡面的student串列資料一一取得
  2. {{student.id}}顯示自動編號的 id 欄位,其餘的也是如此
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>顯示所有資料</title>
</head>
<body>
    <h2>顯示 student資料表所有資料</h2>

    {% for student in students %}    
    編號: {{student.id}}  <br  />
    姓名: {{student.cName}}  <br  />
    性別: {{student.cSex}}  <br  />
    生日: {{student.cBirthday}}  <br  />
    郵件帳號: {{student.cEmail}}  <br  />
    電話: {{student.cPhone}}  <br  />
    地址: {{student.cAddr}}  <br  />
    <br  />
    {% endfor %}
</body>
</html>

最後記得在<urls.py>新增listall的url路徑(或是去掉之前的註解)

網頁執行結果如下:

33.JPG

 

這樣子看資料很不方便,所以最後我們在<listall.html>幫我們的資料加上table語法,讓資料整齊地以表格的方式顯示

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>顯示所有資料</title>
</head>
<body>
    <h2>顯示 student資料表所有資料</h2>
    <table border="1" cellpadding="0" cellspacing="0">
        <th>編號</th>
        <th>姓名</th>
        <th>性別</th>
        <th>生日</th>
        <th>郵件帳號</th>
        <th>電話</th>
        <th>地址</th>
    
        {% for student in students %}    
        <tr>
            <td>{{student.id}}  </td>
            <td>{{student.cName}}  </td>
            <td>{{student.cSex}}  </td>
            <td>{{student.cBirthday}}  </td>
            <td>{{student.cEmail}}  </td>
            <td>{{student.cPhone}}  </td>
            <td>{{student.cAddr}}  </td>
        </tr>
        {% endfor %}
    
    </table>
</body>
</html>

 

最後網頁執行結果如下:

34.JPG

 

 

四、網頁基礎模版:

網站個網頁通常會採用相同風格,例如同樣的頁首頁尾,所以會將相同的部分抽離出來,另外建立模版。

1. 建立網頁基礎模版

在基礎模版中,首先將共同的部份抽離出來,也可以以「{% block 名稱 %}{% endblock %}」來定義區塊

呼叫模版必須以「{% extends 基礎模版 %}」來繼承基礎模版,並設定block區塊內容

以下將以<listall.html>樣版為例,將其拆解為<base.html>與<index.html>

範例3. 建立網頁模版與繼承模版

首先先在studentsapp裡的<view.py>寫一個名為index的自訂函數,其內容同listall,但指向的網址要改為"index.html"

接著在templates目錄中創建一個<base.html>模版

  1. 以block定義title區塊
  2. 在body中定義content區塊
<!DOCTYPE html>
<html>
    <head>
        <!-- 以block定義title區塊 -->
        {% block title %}{% endblock %}
    </head>
    <body>
        <!-- 以block定義content區塊 -->
        {% block content %} {% endblock %}
    </body>
</html>

最後在templates目錄中創建一個<index.html>模版

  1. 繼承 <base.html>基礎模版
  2. 建立title區建立content區塊
  3. 設定網頁主題
  4. 建立表格顯示所有資料

在body中定義content區塊

{% extends 'base.html' %}

{% block title %}
<meta charset="utf-8">
<title>顯示所有資料</title>
{% endblock %}

{% block content %}
    <h2>顯示 student資料表所有資料</h2>
    <table border="1" cellpadding="0" cellspacing="0">
        <th>編號</th>
        <th>姓名</th>
        <th>性別</th>
        <th>生日</th>
        <th>郵件帳號</th>
        <th>電話</th>
        <th>地址</th>
    
        {% for student in students %}    
        <tr>
            <td>{{student.id}}  </td>
            <td>{{student.cName}}  </td>
            <td>{{student.cSex}}  </td>
            <td>{{student.cBirthday}}  </td>
            <td>{{student.cEmail}}  </td>
            <td>{{student.cPhone}}  </td>
            <td>{{student.cAddr}}  </td>
        </tr>
        {% endfor %}
    
    </table>
{% endblock %}

最後網頁執行結果如下:

35.JPG

arrow
arrow
    全站熱搜

    ivankao 發表在 痞客邦 留言(1) 人氣()