This guide will walk you through setting up a Django project named core and creating a simple application, gt, which will render a table using the Great Tables library.
-
Create a New Django Project
Start by creating a new Django project called
core:django-admin startproject core . -
Create a New Django App
Next, create a new Django app named
gt:python manage.py startapp gt
-
Add the
gtApp toINSTALLED_APPSInclude the
gtapp in theINSTALLED_APPSlist within thecore/settings.pyfile:# core/settings.py INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "gt", ]
-
Create a
urls.pyin thegtAppCreate a
urls.pyfile in thegtapp to define your app’s URL patterns:# gt/urls.py from django.urls import path from . import views urlpatterns = [ path("", views.index, name="index"), ]
-
Include
gt/urls.pyin the Project’surls.pyModify the
core/urls.pyfile to include thegtapp’s URLs:# core/urls.py from django.contrib import admin from django.urls import include, path urlpatterns = [ path("admin/", admin.site.urls), path("", include("gt.urls")), ]
-
Create the
indexViewEdit the
gt/views.pyfile to define theindexview. This view will generate an HTML table usingGT.as_raw_html():# 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°N."), ) .sub_missing(missing_text="") ) context = {"sza_gt": sza_gt.as_raw_html()} return render(request, "gt/index.html", context)
-
Set Up the Template
Create a
templatesdirectory within thegtapp. Insidetemplates, create another directory namedgt. Then, create anindex.htmlfile in thegtdirectory. This file will render the HTML table generated in theindexview. Remember to use thesafetemplate tag to prevent Django from escaping the 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>
-
Migrate the Database
Apply migrations to set up your database:
python manage.py migrate
-
Run the Development Server
Finally, start the development server and open your browser to view the rendered table:
python manage.py runserver
If you prefer not to use the safe template tag method, you can adopt the mark_safe() approach in the view instead. Here’s a possible implementation for your reference:
# gt/views.py
from functools import cache
import polars as pl
from django.shortcuts import render
from django.utils.safestring import mark_safe
from great_tables import GT, html
from great_tables.data import sza
def mark_gt_safe(gt):
if isinstance(gt, GT):
return mark_safe(gt.as_raw_html())
return gt
@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°N."),
)
.sub_missing(missing_text="")
)
context = {"sza_gt": mark_gt_safe(sza_gt)}
return render(request, "gt/index.html", context)By doing this, you can use {{ sza_gt }} instead of {{ sza_gt | safe }} in the template.
You should now see the table displayed in your browser at http://127.0.0.1:8000.