iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Python

眾裏尋它:Python表格利器Great Tables系列 第 26

[Day26] - 如何與Django整合 - 靜態表格

  • 分享至 

  • xImage
  •  

今天我們來說明如何將gt表格呈現於Django app中,內容參考自官方Solar Zenith Angles範例

步驟1:建立django project

建立一個名為core的django project。

django-admin startproject core .

步驟2:建立django app

建立一個名為gt的django app(以下簡稱為gt app)。

python manage.py startapp gt

步驟3:將app加入到project中

gt app加入位於core/settings.py內的INSTALLED_APPS中。

# core/settings.py

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "gt",
]

步驟4:建立app的URL pattern

gt app中建立urls.py,並設定urlpatterns

# gt/urls.py

from django.urls import path
from . import views

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

步驟5:將app的URL pattern加入至project中

修改core/urls.py,加入gt appurlpatterns

# core/urls.py

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

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("gt.urls")),
]

步驟6:建立index()函數

 # gt/views.py

 from functools import cache

 import polars as pl
 from django.shortcuts import render
 from great_tables import GT, html
 from great_tables.data import sza


 @cache
 def get_sza():
     return pl.from_pandas(sza)


 def index(request):
     sza_pivot = (
         get_sza()
         .filter((pl.col("latitude") == "20") & (pl.col("tst") <= "1200"))
         .select(pl.col("*").exclude("latitude"))
         .drop_nulls()
         .pivot(values="sza", index="month", on="tst", sort_columns=True)
     )

     sza_gt = (
         GT(sza_pivot, rowname_col="month")
         .data_color(
             domain=[90, 0],
             palette=["rebeccapurple", "white", "orange"],
             na_color="white",
         )
         .tab_header(
             title="Solar Zenith Angles from 05:30 to 12:00",
             subtitle=html("Average monthly values at latitude of 20&deg;N."),
         )
         .sub_missing(missing_text="")
     )

     context = {"sza_gt": sza_gt.as_raw_html()}

     return render(request, "gt/index.html", context)

分段說明如下:

  • get_sza()會返回一個Polars DataFrame,是由gt提供的sza Pandas DataFrame轉換而來。由於DataFrame於此app中不會變動,所以可以將@cache(註1)裝飾在get_sza()上。
  • 定義index()為使用者以HTTP GET訪問「"/"」時使用的函數。
  • sza_pivot為Polars DataFrame的整理過程;sza_gt則為表格的製作過程。
  • context = {"sza_gt": sza_gt.as_raw_html()}為整合的關鍵。我們使用GT.as_raw_html()來生成HTML,並置於context中。
  • 使用render()來回傳index.html。其中,context可以視為製作index.html所需要的額外資訊。

步驟7:建立index.html

gt app中建立一個templates資料夾,並於templates資料夾中再建立一個gt資料夾。最後於此資料夾中(即gt/templates/gt)建立index.html

 <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Django-GT Website</title>
  </head>
  <body>
    <main>
        <h1 style="text-align:center">Great Tables shown in Django</h1>  
    </main>
    <div>
        {{ sza_gt | safe}}
    </div>
  </body>
</html>

index.html中,我們可以使用Django template語法{{ sza_gt }}來取得於context所傳入的值。但請注意這邊必須使用| safe這個filter來確認此HTML是安全的,如此才可於瀏覽器中順利呈現gt表格。

步驟8:執行migration(optional)

由於gt app並沒有使用到資料庫,所以此命令為選擇性執行。如果沒有執行,gt表格也可正確呈現,只是命令列會有尚未migration的警告訊息。

python manage.py migrate

步驟9:啟動Django development server

於命令列中執行下列指令:

python manage.py runserver

接著打開瀏覽器前往預設網址,如http://127.0.0.1:8000/,就可以見到下面這個漂亮的表格:

table

其它參考作法

如果不喜歡於template中加入| safe的話,可以改為在view function中添加。舉例來說,可以寫一個mark_gt_safe()來幫忙在index()中呼叫GT.as_raw_html()

# gt/views.py
...
from django.utils.safestring import mark_safe


def mark_gt_safe(gt):
 if isinstance(gt, GT):
     return mark_safe(gt.as_raw_html())
 return gt


def index(request):

    ...

    context = {"sza_gt": mark_gt_safe(sza_gt)}

    return render(request, "gt/index.html", context)

這麼一來在index.html中,就可以直接使用{{ sza_gt }}來取得gt表格的HTML格式,而不必使用{{ sza_gt | safe}}了。

如果對裝飾器這個概念仍然不是那麼清楚的朋友,可以參考我於2023年鐵人賽的系列文 ── Python十翼:與未來的自己對話,其中有詳細的說明。

Code

本日所有程式碼可參考gt-django repo。


上一篇
[Day25] - 如何與FastAPI整合 - 靜態表格
下一篇
[Day27] - 如何與Panel整合 - 靜態與動態表格
系列文
眾裏尋它:Python表格利器Great Tables30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言