Migrate web frontend to docusaurus and copy over existing notes to new format

This commit is contained in:
Keannu Bernasol 2024-10-14 18:17:08 +08:00
parent 81ec3e90ed
commit 77471093c4
133 changed files with 17275 additions and 58 deletions

28
.gitignore vendored
View file

@ -1,6 +1,32 @@
## Obsidian
# to exclude Obsidian's settings (including plugin and hotkey configurations) # to exclude Obsidian's settings (including plugin and hotkey configurations)
.obsidian/ .obsidian/
# Add below lines to exclude OS settings and caches # Add below lines to exclude OS settings and caches
.trash/ .trash/
.DS_Store .DS_Store
## Docusaurus
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View file

@ -1,3 +1 @@
A Git-mirrored copy of my blog posts, guides, and public notes A Git-mirrored copy of my [Obsidian](https://obsidian.md/) blog posts, guides, and public notes, served publicly using [Docusaurus](https://github.com/facebook/docusaurus)
#### Resource List
- [Django REST Framework Setup](Django%20REST%20Framework%20Guide/1_Setup.md)

3
babel.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

1
blog/Sample Post.md Normal file
View file

@ -0,0 +1 @@
Work in progress!

View file

@ -0,0 +1,22 @@
- Mount a CIFS/Samba File share in Linux
```bash
sudo mount -t cifs //$ADDRESS/$REMOTE_PATH /$LOCAL_PATH \
-o username=$USERNAME,password=$PASSWORD
```
- Mount a CIFS/Samba File Share in Linux with a credentials file
```bash
sudo mount -t cifs //$ADDRESS/$REMOTE_PATH /$LOCAL_PATH \
-o credentials=/root/.samba/credentials
```
`credentials`file
```
username=value
password=value
```
- Restore most recent Borg backup snapshot
```bash
borg extract --strip-components 3 /mnt/backups/$DEVICE/$BACKUP_NAME::$SNAPSHOT_NAME
# Extract latest snapshot
borg extract --strip-components 3 /mnt/backups/$DEVICE/$BACKUP_NAME::$(borg list /mnt/backups/$BACKUP_NAME --last 1 --short)
```

View file

@ -0,0 +1,9 @@
Create CIFS/Samba Volume
```bash
docker volume create \
--driver local \
--opt type=cifs \
--opt device=//uxxxxx.your-server.de/backup \
--opt username=USERNAME,password=PASSWORD,file_mode=0777,dir_mode=0777 \
--name VOLUME_NAME
```

View file

@ -0,0 +1,164 @@
- [QBittorrent](https://ghcr.io/hotio/qbittorrent)
```bash
docker run \
--restart=always \
--name qbittorrent \
-d \
-p 8088:8080 \
-p 57189:57189 \
-e PUID=1000 \
-e PGID=1000 \
-e UMASK=002 \
-e TZ="Asia/Manila" \
-v /mnt/nvme/docker-volume-mounts/vuetorrent:/config \
-v /mnt:/mnt \
ghcr.io/hotio/qbittorrent
```
- [Unbound](https://hub.docker.com/r/mvance/unbound) (DNS Resolver)
```bash
docker run \
--name=unbound-rpi \
--publish=5335:53/udp \
--publish=5335:53/tcp \
--restart=always \
--detach=true \
mvance/unbound-rpi:latest
```
- [Uptime Kuma](https://github.com/louislam/uptime-kuma)
```bash
docker run \
-d \
--restart=always \
-p 8082:3001 \
-v /mnt/sda1/docker-volume-mounts/uptime-kuma:/app/data \
--name uptime-kuma \
louislam/uptime-kuma:1
```
- OpenStreetMap
```bash
# Import .pbf file
docker run \
-v /mnt/sdb1/files/docker\ projects/tileserver/philippines-latest.osm.pbf:/data/region.osm.pbf \
-v /mnt/sdb1/docker-volume-mounts/osm-data:/data/database/ \
-v /mnt/sdb1/docker-volume-mounts/osm-tiles:/data/tiles/ \
overv/openstreetmap-tile-server \
import
# Run OSM tileserver
docker run \
-p 8084:80 \
-e THREADS=4 \
-e ALLOW_CORS=enabled \
-v /mnt/sdb1/docker-volume-mounts/osm-data:/data/database/ \
-v /mnt/sdb1/docker-volume-mounts/osm-tiles:/data/tiles/ \
-d overv/openstreetmap-tile-server \
--name osm-tileserver \
run
# Pre-render Cagayan de Oro City
# Set folder permissions for osm-tiles to 777 otherwise tiles may not be saved
# Run this via tmux or screen as this might take a while
tmux new-session -d -s "Render OSM Tiles" 'docker exec -it osm-tileserver "git clone https://github.com/alx77/render_list_geo.pl && cd render_list_geo.pl && ./render_list_geo.pl -n 4 -z 3 -Z 18 -x 124.33 -X 124.94 -y 8.13 -Y 8.65 -m default"'
```
- [Minetest](https://lscr.io/linuxserver/minetest)
```bash
docker run -d \
--name=minetest \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Manila \
-e CLI_ARGS="--gameid minetest --port 30000" `#optional` \
-p 30000:30000/udp \
-v /mnt/sda1/docker-volume-mounts/minetest:/config/.minetest \
--restart always\
lscr.io/linuxserver/minetest:latest
```
- [Jellyfin](https://github.com/jellyfin/jellyfin) (via [jellyfin-mpp](https://hub.docker.com/r/jjm2473/jellyfin-mpp) fork for Orange Pi 5 support)
```bash
docker run --name jellyfin \
--privileged \
--restart=unless-stopped -td \
`for dev in iep rga dri dma_heap mpp_service mpp-service vpu_service vpu-service \
hevc_service hevc-service rkvdec rkvenc avsd vepu h265e ; do \
[ -e "/dev/$dev" ] && echo " --device /dev/$dev"; \
done` \
--dns=172.17.0.1 \
-p 8091:8096 \
-v /mnt/sda1/docker-volume-mounts/jellyfin/config:/config \
-v /mnt:/mnt \
jjm2473/jellyfin-mpp:latest
```
- [Sonarr](https://lscr.io/linuxserver/sonarr)
```bash
docker run -d \
--name=sonarr \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Manila \
-p 8092:8989 \
-v /mnt/sda1/docker-volume-mounts/sonarr:/config \
-v /mnt:/mnt \
--restart always \
lscr.io/linuxserver/sonarr:latest
```
- [Prowlarr](https://lscr.io/linuxserver/prowlarr)
```
docker run -d \
--name=prowlarr \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Manila \
-p 8093:9696 \
-v /mnt/sda1/docker-volume-mounts/prowlarr:/config \
--restart always \
lscr.io/linuxserver/prowlarr:latest
```
- [Jackett](https://ghcr.io/hotio/jackett)
```bash
docker run --rm \
--name jackett \
-p 8094:9117 \
-e PUID=1000 \
-e PGID=1000 \
-e UMASK=002 \
-e TZ="Asia/Manila" \
-v /mnt/sda1/docker-volume-mounts/jackett:/config \
ghcr.io/hotio/jackett
```
- [Firefox Container](https://lscr.io/linuxserver/firefox)
```bash
docker run \
-d \
--name=firefox \
--security-opt seccomp=unconfined \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Manila \
-p 3001:3000 \
-v /mnt/nvme/docker-volume-mounts/firefox-config:/config \
--shm-size="2gb" \
--restart always \
lscr.io/linuxserver/firefox:latest
```
- [Prometheus](https://hub.docker.com/r/prom/prometheus)
```bash
docker run \
-p 9090:9090 \
-v /mnt/nvme/docker-volume-mounts/prometheus:/etc/prometheus \
--restart unless-stopped \
prom/prometheus
```
- [Inbucket](https://hub.docker.com/r/inbucket/inbucket/)
```bash
docker run -d --restart=always --name inbucket \
-p 8025:8025 \
-e INBUCKET_MAILBOXNAMING="domain" \
-e INBUCKET_WEB_ADDR="0.0.0.0:8025" \
-e INBUCKET_STORAGE_TYPE="file" \
-e INBUCKET_STORAGE_PARAMS="path:/mnt/sda1/docker-volume-mounts/inbucket" \
-e INBUCKET_STORAGE_RETENTIONPERIOD="4h" \
-e INBUCKET_STORAGE_MAILBOXMSGCAP="5000" \
inbucket/inbucket:latest
```

View file

@ -0,0 +1,98 @@
### Windows Apps
#### [Powertoys](https://learn.microsoft.com/en-us/windows/powertoys/)
![image.png](_resources/Files%20&%20Links/4d5d6b317ec6df91ca6b10704a97d07f_MD5.jpg)
- Color picker feature is a must-have for color sampling
- Text extractor helps with image-only PDFs
- Official app from Microsoft
#### [EqualizerAPO](https://equalizerapo.com/download.html)
![image.png](_resources/Files%20&%20Links/7a176cd31a8e22592f4b6d731180ff2a_MD5.jpg)
- Install this and follow the guide [here](https://medium.com/@bssankaran/free-and-open-source-software-noise-cancelling-for-working-from-home-edb1b4e9764e) to set up noise cancellation for any microphone.
- Minimizes background noise (fans, chatter, etc.) even on low end webcam mics
#### [Windows Update Blocker](https://www.sordum.org/9470/windows-update-blocker-v1-8/)
![image.png](_resources/Files%20&%20Links/8dbf0f28e252cf0ec094bcb50f890003_MD5.jpg)
- Blocks Windows 8/10/11 updates
- Good to use with low end laptops/devices
- Reversible. If you want updates, just re-enable in-app
#### [Compactor](https://github.com/Freaky/Compactor)
![image.png](_resources/Files%20&%20Links/f4b49dac88ba1e917f500271058b3c71_MD5.jpg)
- Uses Windows compression to reduce size of games
- Alternative to [CompactGUI](https://github.com/IridiumIO/CompactGUI)
- Compression results are dependent on the game. Make sure to cross-check in their list [here](https://docs.google.com/spreadsheets/d/14CVXd6PTIYE9XlNpRsxJUGaoUzhC5titIC1rzQHI4yI/edit?gid=0#gid=0)
#### [Magpie](https://github.com/Blinue/Magpie)
![image.png](_resources/Files%20&%20Links/008c3e51e4801e36e983c4ed9de689f1_MD5.jpg)
- Must-have for low end gaming
- Adds AMD FSR scaling to games that do not natively support it, allowing you to run at 480p and upscale to 720p/1080p to boost FPS
#### [Link Shell Extension](https://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html)
![image.png](_resources/Files%20&%20Links/f36d4ea2e5e36ff09da5351f2476a089_MD5.jpg)
- Lets you quickly create Linux-equivalent symbolic links in Windows
#### [RBTray](https://rbtray.sourceforge.net/)
- Lets you hide apps that may not be hidden otherwise in the taskbar
#### [Syncthing](https://syncthing.net)
![image.png](_resources/Files%20&%20Links/b5e308dd2ce5f281a2066d8076df2bf3_MD5.jpg)
- File synchronization app for Windows/Android
- Can sync music, photos, and other files/folders between devices
### Android Apps
#### [Seal](https://github.com/JunkFood02/Seal)
![3.jpg](_resources/Files%20&%20Links/28b7a00bb043f5f91f6f163beaf66108_MD5.jpg)
- Video downloader for Youtube and other sources
- Best used with Youtube Revanced
### GitHub Lists (Unsorted)
- [https://github.com/tanprathan/MobileApp-Pentest-Cheatsheet](https://github.com/tanprathan/MobileApp-Pentest-Cheatsheet)
- [https://github.com/Psyhackological/AAA](https://github.com/Psyhackological/AAA)
- [https://github.com/amitshekhariitbhu/android-developer-roadmap](https://github.com/amitshekhariitbhu/android-developer-roadmap)
- [https://github.com/pawelborkar/awesome-repos](https://github.com/pawelborkar/awesome-repos)
- [https://github.com/public-apis/public-apis](https://github.com/public-apis/public-apis)
- [https://github.com/christian-bromann/awesome-selenium](https://github.com/christian-bromann/awesome-selenium)
- [https://github.com/sindresorhus/awesome](https://github.com/sindresorhus/awesome)
- [https://github.com/anderspitman/awesome-tunneling](https://github.com/anderspitman/awesome-tunneling)
- [https://github.com/atinfo/awesome-test-automation](https://github.com/atinfo/awesome-test-automation)
- [https://github.com/dipakkr/A-to-Z-Resources-for-Students](https://github.com/dipakkr/A-to-Z-Resources-for-Students)
- [https://github.com/dipakkr/A-to-Z-Resources-for-Students](https://github.com/dipakkr/A-to-Z-Resources-for-Students)
- [https://github.com/anderspitman/awesome-tunneling](https://github.com/anderspitman/awesome-tunneling)
- [https://github.com/luong-komorebi/Awesome-Linux-Software](https://github.com/luong-komorebi/Awesome-Linux-Software)
- [https://github.com/mikeroyal/Self-Hosting-Guide](https://github.com/mikeroyal/Self-Hosting-Guide)
- [https://github.com/ripienaar/free-for-dev](https://github.com/ripienaar/free-for-dev)
- [https://github.com/awesome-selfhosted/awesome-selfhosted](https://github.com/awesome-selfhosted/awesome-selfhosted)
- [https://github.com/vaib25vicky/awesome-mobile-security](https://github.com/vaib25vicky/awesome-mobile-security)
- [https://github.com/cloudcommunity/Cloud-Free-Tier-Comparison](https://github.com/cloudcommunity/Cloud-Free-Tier-Comparison)
### Sites/Web Apps
- [https://uptimerobot.com/](https://uptimerobot.com/) - Uptime Kuma alternative
- [https://colab.research.google.com/](https://colab.research.google.com/) - For running `.ipynb` notebooks
- [https://datasetsearch.research.google.com/](https://datasetsearch.research.google.com/) - Datasets for machine learning
- [https://www.kaggle.com/](https://www.kaggle.com/) -For running `.ipynb` notebooks, also has datasets for machine learning
- [https://phind.com](https://phind.com) - ChatGPT alternative
- [https://perplexity.ai](https://perplexity.ai) - ChatGPT alternative
- [https://try.cloudflare.com/](https://try.cloudflare.com/) - Free domain with HTTP SSL certificate via Cloudflared
### Extensions (Browser/VSCode)
- [https://github.com/Dj0ulo/OptiSearch](https://github.com/Dj0ulo/OptiSearch)
- Custom VSCode Theme
- https://marketplace.visualstudio.com/items?itemName=leandro-rodrigues.fluent-ui-vscode
- [https://marketplace.visualstudio.com/items?itemName=illixion.vscode-vibrancy-continued](https://marketplace.visualstudio.com/items?itemName=illixion.vscode-vibrancy-continued)
- Terminal tab may be broken. You can fix it by following this below
[https://github.com/TheOld/vscode-fluent-ui/issues/53](https://github.com/TheOld/vscode-fluent-ui/issues/53)
- Edit workbench.html file at
```
Microsoft VS Code\resources\app\out\vs\code\electron-sandbox\workbench
```
### Framework Libraries
- [https://leafletjs.com/](https://leafletjs.com/)
- [https://react-leaflet.js.org/](https://react-leaflet.js.org/)
- [https://ant.design/components/overview/](https://ant.design/components/overview/)
- [https://github.com/pennersr/django-allauth](https://github.com/pennersr/django-allauth)
### Other Links
- [https://profy.dev/article/react-folder-structure](https://profy.dev/article/react-folder-structure)
- [https://developers.cloudflare.com/pages/platform/limits/](https://developers.cloudflare.com/pages/platform/limits/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

View file

@ -1,12 +1,10 @@
# Setup
### Overview ### Overview
Django is a framework built with Python to help you implement web applications. Django is a framework built with Python to help you implement web applications.
![353e9c415078b3d4a18d7bd93294df1c_MD5](_resources/1_Setup/353e9c415078b3d4a18d7bd93294df1c_MD5.jpg) ![353e9c415078b3d4a18d7bd93294df1c_MD5](_resources/1%20-%20Setup/353e9c415078b3d4a18d7bd93294df1c_MD5.jpg)
![8d193fcb83f676cd16e263f78f965bc5_MD5](_resources/1_Setup/8d193fcb83f676cd16e263f78f965bc5_MD5.jpg) ![8d193fcb83f676cd16e263f78f965bc5_MD5](_resources/1%20-%20Setup/8d193fcb83f676cd16e263f78f965bc5_MD5.jpg)
Django can be used as-is to develop full stack web apps which include your frontend and backend. This however isn't the focus of this guide. Django can be used as-is to develop full stack web apps which include your frontend and backend. This however isn't the focus of this guide.
@ -18,21 +16,21 @@ This guide has concepts that are similar to the official guide for Django linked
You will need to install the latest version of Python (version 3.11.2 as of 2/19/2023) You will need to install the latest version of Python (version 3.11.2 as of 2/19/2023)
[<span style="margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-family: inherit; font-size: 16px; vertical-align: baseline; outline: 0px;">https://www.python.org/downloads/</span>](https://www.python.org/downloads/ "https://www.python.org/downloads/") [https://www.python.org/downloads/](https://www.python.org/downloads/ "https://www.python.org/downloads/")
<span style="margin: 0px; padding: 0px; border: 0px; font-weight: inherit; font-style: inherit; font-family: inherit; font-size: 16px; vertical-align: baseline; outline: 0px;">During the installation, make sure to check **Add Python 3.x to PATH**</span> During the installation, make sure to check **Add Python 3.x to PATH**
![373ea207d1abd6f0a734506d8ab4acbc_MD5](_resources/1_Setup/373ea207d1abd6f0a734506d8ab4acbc_MD5.jpg) ![373ea207d1abd6f0a734506d8ab4acbc_MD5](_resources/1%20-%20Setup/373ea207d1abd6f0a734506d8ab4acbc_MD5.jpg)
To check if you have a working install, open a command line (CMD) and type in `python --version` To check if you have a working install, open a command line (CMD) and type in `python --version`
![5d1081e556bd19260f14a235fef4e383_MD5](_resources/1_Setup/5d1081e556bd19260f14a235fef4e383_MD5.jpg) ![5d1081e556bd19260f14a235fef4e383_MD5](_resources/1%20-%20Setup/5d1081e556bd19260f14a235fef4e383_MD5.jpg)
If this does not work, you will have to check your PATH variables. If it does, you can safely proceed to the next step. If this does not work, you will have to check your PATH variables. If it does, you can safely proceed to the next step.
![3ed75d2e3ff3aad581b4cd7c2af748a3_MD5](_resources/1_Setup/3ed75d2e3ff3aad581b4cd7c2af748a3_MD5.jpg) ![3ed75d2e3ff3aad581b4cd7c2af748a3_MD5](_resources/1%20-%20Setup/3ed75d2e3ff3aad581b4cd7c2af748a3_MD5.jpg)
![aef7461456894804006fa820f6a2061e_MD5](_resources/1_Setup/aef7461456894804006fa820f6a2061e_MD5.jpg) ![aef7461456894804006fa820f6a2061e_MD5](_resources/1%20-%20Setup/aef7461456894804006fa820f6a2061e_MD5.jpg)
### Install [Pipenv](https://pipenv.pypa.io/en/latest/) ### Install [Pipenv](https://pipenv.pypa.io/en/latest/)
@ -58,7 +56,7 @@ Open up a command line (CMD) and type in `pip install --user pipenv` to install
This will use the package manager for Python (akin to npm for Javascript/Typescript projects) to install the Pipenv package This will use the package manager for Python (akin to npm for Javascript/Typescript projects) to install the Pipenv package
![8e0864b9971e3e0ec0843db1494a9164_MD5](_resources/1_Setup/8e0864b9971e3e0ec0843db1494a9164_MD5.jpg) ![8e0864b9971e3e0ec0843db1494a9164_MD5](_resources/1%20-%20Setup/8e0864b9971e3e0ec0843db1494a9164_MD5.jpg)
### Install [Git](https://git-scm.com/downloads) ### Install [Git](https://git-scm.com/downloads)
@ -66,10 +64,10 @@ When developing applications, you will need to use version control to track chan
Head over to the [downloads](https://git-scm.com/downloads/win) page and install the 64-bit Git for Windows Setup version (Standalone Installer) Head over to the [downloads](https://git-scm.com/downloads/win) page and install the 64-bit Git for Windows Setup version (Standalone Installer)
![c2f115b66c9b0f4e93ea54d1091f9696_MD5](_resources/1_Setup/c2f115b66c9b0f4e93ea54d1091f9696_MD5.jpg) ![c2f115b66c9b0f4e93ea54d1091f9696_MD5](_resources/1%20-%20Setup/c2f115b66c9b0f4e93ea54d1091f9696_MD5.jpg)
This guide does not cover the proper usage of Git and so you may need to look up for other resources if you are not familiar with it yet. This guide does not cover the proper usage of Git and so you may need to look up for other resources if you are not familiar with it yet.
![6198958f0bad6ed532a840df3435ad23_MD5](_resources/1_Setup/6198958f0bad6ed532a840df3435ad23_MD5.jpg) ![6198958f0bad6ed532a840df3435ad23_MD5](_resources/1%20-%20Setup/6198958f0bad6ed532a840df3435ad23_MD5.jpg)
You can proceed with the typical installation using defaults (no need to change anything), just click Next/Install. You can proceed with the typical installation using defaults (no need to change anything), just click Next/Install.
With that out of the way, you can proceed to setting up your Django REST Framework project. With that out of the way, you can proceed to setting up your Django REST Framework project.

View file

@ -1,46 +1,44 @@
# Initialize your first Project
### Start a New Project ### Start a New Project
With your tooling properly set up in the previous chapter, you can now start with setting up your Django project. With your tooling properly set up in the previous chapter, you can now start with setting up your Django project.
Create a new folder for your project. Create a new folder for your project.
![4d6ba511be479a6749bc4baeb985aa54_MD5](_resources/2_Initialize_Your_First_Project/4d6ba511be479a6749bc4baeb985aa54_MD5.jpg) ![4d6ba511be479a6749bc4baeb985aa54_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/4d6ba511be479a6749bc4baeb985aa54_MD5.jpg)
And open the folder in your editor of choice, such as VSCode And open the folder in your editor of choice, such as VSCode
![da331137b939a5faf4924ee8a21b3fca_MD5](_resources/2_Initialize_Your_First_Project/da331137b939a5faf4924ee8a21b3fca_MD5.jpg) ![da331137b939a5faf4924ee8a21b3fca_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/da331137b939a5faf4924ee8a21b3fca_MD5.jpg)
Create a new Python virtual environment with Pipenv by running `pipenv shell` Create a new Python virtual environment with Pipenv by running `pipenv shell`
![db56664f1d7fb30451131394845729c5_MD5](_resources/2_Initialize_Your_First_Project/db56664f1d7fb30451131394845729c5_MD5.jpg) ![db56664f1d7fb30451131394845729c5_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/db56664f1d7fb30451131394845729c5_MD5.jpg)
This will create a Pipfile in your project folder. This will track what packages you install in your virtual environment This will create a Pipfile in your project folder. This will track what packages you install in your virtual environment
![3567fe21bc31ff29f392e112cd1e9308_MD5](_resources/2_Initialize_Your_First_Project/3567fe21bc31ff29f392e112cd1e9308_MD5.jpg) ![3567fe21bc31ff29f392e112cd1e9308_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/3567fe21bc31ff29f392e112cd1e9308_MD5.jpg)
I highly suggest you install the [Python VSCode extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) at this step to help with your developer experience I highly suggest you install the [Python VSCode extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) at this step to help with your developer experience
![4997f4d3a648a6ab9f5ac19c8211374f_MD5](_resources/2_Initialize_Your_First_Project/4997f4d3a648a6ab9f5ac19c8211374f_MD5.jpg) ![4997f4d3a648a6ab9f5ac19c8211374f_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/4997f4d3a648a6ab9f5ac19c8211374f_MD5.jpg)
### Initialize Git ### Initialize Git
When working on software projects such as Django, you will need to be able to track small changes. We'll be using Git for that When working on software projects such as Django, you will need to be able to track small changes. We'll be using Git for that
We previously installed Git, now's the time to use it. In your terminal, run the command `git init` We previously installed Git, now's the time to use it. In your terminal, run the command `git init`
![765336c9701ec47364bcd428b580e1ce_MD5](_resources/2_Initialize_Your_First_Project/765336c9701ec47364bcd428b580e1ce_MD5.jpg) ![765336c9701ec47364bcd428b580e1ce_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/765336c9701ec47364bcd428b580e1ce_MD5.jpg)
If successful, this will create a hidden `.git` folder in your project If successful, this will create a hidden `.git` folder in your project
![f1c979f796fda6b41f83a37744b469e2_MD5](_resources/2_Initialize_Your_First_Project/f1c979f796fda6b41f83a37744b469e2_MD5.jpg) ![f1c979f796fda6b41f83a37744b469e2_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/f1c979f796fda6b41f83a37744b469e2_MD5.jpg)
There are some files in your projects that won't need to be tracked for changes (database files, and passwords!) There are some files in your projects that won't need to be tracked for changes (database files, and passwords!)
\ \
Download the `gitignore` below and rename it to `.gitignore`. You can then drop it into your root project folder Download the `gitignore` below and rename it to `.gitignore`. You can then drop it into your root project folder
![gitignore](_resources/2_Initialize_Your_First_Project/gitignore) ![gitignore](_resources/2%20-%20Initialize%20your%20First%20Project/gitignore)
![d5a36b65d64255b05bc81a1709ca1158_MD5](_resources/2_Initialize_Your_First_Project/d5a36b65d64255b05bc81a1709ca1158_MD5.jpg) ![d5a36b65d64255b05bc81a1709ca1158_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/d5a36b65d64255b05bc81a1709ca1158_MD5.jpg)
Don't forget to rename it to `.gitignore`. Take note of the dot before the filename! Don't forget to rename it to `.gitignore`. Take note of the dot before the filename!
@ -52,11 +50,11 @@ Since you're using a virtual environment such as Pipenv, you will need to specif
Press **CTRL + Shift + P** to open the VSCode menu and type in **Select Interpreter**. Press **CTRL + Shift + P** to open the VSCode menu and type in **Select Interpreter**.
![d4da2b316a92c4444c01272187355abd_MD5](_resources/2_Initialize_Your_First_Project/d4da2b316a92c4444c01272187355abd_MD5.jpg) ![d4da2b316a92c4444c01272187355abd_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/d4da2b316a92c4444c01272187355abd_MD5.jpg)
Select the virtual Python environment you created earlier (eg. the one created from `pipenv shell`) Select the virtual Python environment you created earlier (eg. the one created from `pipenv shell`)
![9d0f73aa1a1929a62a482e23bf2e94b5_MD5](_resources/2_Initialize_Your_First_Project/9d0f73aa1a1929a62a482e23bf2e94b5_MD5.jpg) ![9d0f73aa1a1929a62a482e23bf2e94b5_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/9d0f73aa1a1929a62a482e23bf2e94b5_MD5.jpg)
### Install Dependencies and Packages ### Install Dependencies and Packages
@ -66,32 +64,32 @@ On your current project's code editor, open a terminal or command line and type
`pipenv install django djangorestframework` `pipenv install django djangorestframework`
![0cfa5562ea461edb202130a6f49a7cea_MD5](_resources/2_Initialize_Your_First_Project/0cfa5562ea461edb202130a6f49a7cea_MD5.jpg) ![0cfa5562ea461edb202130a6f49a7cea_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/0cfa5562ea461edb202130a6f49a7cea_MD5.jpg)
This will update your Pipfile and create a Pipfile.lock to reflect the installed packages This will update your Pipfile and create a Pipfile.lock to reflect the installed packages
![bb5d783ca5d693451fc98425856492b9_MD5](_resources/2_Initialize_Your_First_Project/bb5d783ca5d693451fc98425856492b9_MD5.jpg) ![bb5d783ca5d693451fc98425856492b9_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/bb5d783ca5d693451fc98425856492b9_MD5.jpg)
### Initialize the Project ### Initialize the Project
In your code editor's terminal or command prompt, run the command In your code editor's terminal or command prompt, run the command
`django-admin startproject PROJECT\_NAME` `django-admin startproject PROJECT\_NAME`
![9fa2115388cde426285a656a7e9965d5_MD5](_resources/2_Initialize_Your_First_Project/9fa2115388cde426285a656a7e9965d5_MD5.jpg)](https://bookstack.06222001.xyz/uploads/images/gallery/2024-09/i5bimage.png) ![9fa2115388cde426285a656a7e9965d5_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/9fa2115388cde426285a656a7e9965d5_MD5.jpg)](https://bookstack.06222001.xyz/uploads/images/gallery/2024-09/i5bimage.png)
Be sure to replace it with your own project name! I named mine `djangobackend`. Be sure to replace it with your own project name! I named mine `djangobackend`.
A new directory will be created, containing your Django project's files A new directory will be created, containing your Django project's files
[![a137cf212011825e092997818ff20658_MD5](_resources/2_Initialize_Your_First_Project/a137cf212011825e092997818ff20658_MD5.jpg) [![a137cf212011825e092997818ff20658_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/a137cf212011825e092997818ff20658_MD5.jpg)
Change your directory in the terminal to the folder just created eg. `cd PROJECT\_NAME` Change your directory in the terminal to the folder just created eg. `cd PROJECT\_NAME`
![ab38fdac55d8d6331471d609707dfdb9_MD5](_resources/2_Initialize_Your_First_Project/ab38fdac55d8d6331471d609707dfdb9_MD5.jpg) ![ab38fdac55d8d6331471d609707dfdb9_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/ab38fdac55d8d6331471d609707dfdb9_MD5.jpg)
Once that's done, run the command `python manage.py runserver 0.0.0.0:8000` to start your Django project Once that's done, run the command `python manage.py runserver 0.0.0.0:8000` to start your Django project
![b281e8b8bd83d316d45c1d0e810ce0a1_MD5](_resources/2_Initialize_Your_First_Project/b281e8b8bd83d316d45c1d0e810ce0a1_MD5.jpg) ![b281e8b8bd83d316d45c1d0e810ce0a1_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/b281e8b8bd83d316d45c1d0e810ce0a1_MD5.jpg)
Your Django project will now be visible on the URL **[https://localhost:8000](https://localhost:8000)** Your Django project will now be visible on the URL **[https://localhost:8000](https://localhost:8000)**
![377f5134b0525b830116a64d7699368f_MD5](_resources/2_Initialize_Your_First_Project/377f5134b0525b830116a64d7699368f_MD5.jpg) ![377f5134b0525b830116a64d7699368f_MD5](_resources/2%20-%20Initialize%20your%20First%20Project/377f5134b0525b830116a64d7699368f_MD5.jpg)

View file

@ -1,5 +1,3 @@
# Project Structure
### Folder Hierarchy ### Folder Hierarchy
Your project's root folder (the outer most) contains the following Your project's root folder (the outer most) contains the following
@ -9,7 +7,7 @@ Your project's root folder (the outer most) contains the following
#### Project Folder #### Project Folder
![3a9acd103fc5ff4a63a7520951dc99b8_MD5](_resources/3_Project_Structure/3a9acd103fc5ff4a63a7520951dc99b8_MD5.jpg) ![3a9acd103fc5ff4a63a7520951dc99b8_MD5](_resources/3%20-%20Project%20Structure/3a9acd103fc5ff4a63a7520951dc99b8_MD5.jpg)
The folder immediately proceeding your first one contains your Django project, created by the command `django-admin startproject PROJECT\_NAME` which you previously executed The folder immediately proceeding your first one contains your Django project, created by the command `django-admin startproject PROJECT\_NAME` which you previously executed
@ -26,7 +24,7 @@ Django divides your projects into groups called apps. When you start a new proje
In this case, my first app is named `djangobackend` In this case, my first app is named `djangobackend`
![1f40b8e177d08862762cffe20f01e38f_MD5](_resources/3_Project_Structure/1f40b8e177d08862762cffe20f01e38f_MD5.jpg) ![1f40b8e177d08862762cffe20f01e38f_MD5](_resources/3%20-%20Project%20Structure/1f40b8e177d08862762cffe20f01e38f_MD5.jpg)
That seems a bit confusing doesn't it? That seems a bit confusing doesn't it?
@ -36,35 +34,35 @@ To make things clearer, you can opt to rename the main app of your Django projec
- Rename the main app folder to `config` - Rename the main app folder to `config`
![bd12032f298e0a3e9d7c12999b231b77_MD5](_resources/3_Project_Structure/bd12032f298e0a3e9d7c12999b231b77_MD5.jpg) ![bd12032f298e0a3e9d7c12999b231b77_MD5](_resources/3%20-%20Project%20Structure/bd12032f298e0a3e9d7c12999b231b77_MD5.jpg)
- Open `asgi.py` and change line 14 to point to **config.settings** instead of **PROJECT_NAME.settings** - Open `asgi.py` and change line 14 to point to **config.settings** instead of **PROJECT_NAME.settings**
![9a3064d2cb4d17b632358d10dfbdcc22_MD5](_resources/3_Project_Structure/9a3064d2cb4d17b632358d10dfbdcc22_MD5.jpg) ![9a3064d2cb4d17b632358d10dfbdcc22_MD5](_resources/3%20-%20Project%20Structure/9a3064d2cb4d17b632358d10dfbdcc22_MD5.jpg)
- Do the same for the `wsgi.py` file, also in line 14 - Do the same for the `wsgi.py` file, also in line 14
![6846e765a92401a0768a60fab29151f9_MD5](_resources/3_Project_Structure/6846e765a92401a0768a60fab29151f9_MD5.jpg) ![6846e765a92401a0768a60fab29151f9_MD5](_resources/3%20-%20Project%20Structure/6846e765a92401a0768a60fab29151f9_MD5.jpg)
- Go to `settings.py` and set **ROOT_URLCONF** in line 52 to **config.urls** instead of **PROJECT_NAME.urls** - Go to `settings.py` and set **ROOT_URLCONF** in line 52 to **config.urls** instead of **PROJECT_NAME.urls**
![8a0ab212600d24de9fb70656e810e603_MD5](_resources/3_Project_Structure/8a0ab212600d24de9fb70656e810e603_MD5.jpg) ![8a0ab212600d24de9fb70656e810e603_MD5](_resources/3%20-%20Project%20Structure/8a0ab212600d24de9fb70656e810e603_MD5.jpg)
- Do the same for **WSGI_APPLICATION** in `settings.py`, line 70 - Do the same for **WSGI_APPLICATION** in `settings.py`, line 70
![42ab80ce78c1158e8af47ddf9631c027_MD5](_resources/3_Project_Structure/42ab80ce78c1158e8af47ddf9631c027_MD5.jpg) ![42ab80ce78c1158e8af47ddf9631c027_MD5](_resources/3%20-%20Project%20Structure/42ab80ce78c1158e8af47ddf9631c027_MD5.jpg)
- In `manage.py`, change line 19 to point to **config.settings** instead of **PROJECT_NAME.settings** - In `manage.py`, change line 19 to point to **config.settings** instead of **PROJECT_NAME.settings**
[![29904325362d967d3e9fe79941ae3589_MD5](_resources/3_Project_Structure/29904325362d967d3e9fe79941ae3589_MD5.jpg) [![29904325362d967d3e9fe79941ae3589_MD5](_resources/3%20-%20Project%20Structure/29904325362d967d3e9fe79941ae3589_MD5.jpg)
With that, you should be good to go. Double check your setup by starting the Django app once again With that, you should be good to go. Double check your setup by starting the Django app once again
![d85a379bdec6197afff6e37bd79359a2_MD5](_resources/3_Project_Structure/d85a379bdec6197afff6e37bd79359a2_MD5.jpg) ![d85a379bdec6197afff6e37bd79359a2_MD5](_resources/3%20-%20Project%20Structure/d85a379bdec6197afff6e37bd79359a2_MD5.jpg)
If you followed everything correctly, you should see the same page as before If you followed everything correctly, you should see the same page as before
![9e9b9a07ac2b8066670d18d04a97627c_MD5](_resources/3_Project_Structure/9e9b9a07ac2b8066670d18d04a97627c_MD5.jpg) ![9e9b9a07ac2b8066670d18d04a97627c_MD5](_resources/3%20-%20Project%20Structure/9e9b9a07ac2b8066670d18d04a97627c_MD5.jpg)
### Setting up DRF ### Setting up DRF
@ -74,10 +72,10 @@ You've already installed Django REST Framework in the previous steps (e.g. `pipe
To register it as an app in our project. Open your `settings.py` file and look for the **INSTALLED_APPS** section To register it as an app in our project. Open your `settings.py` file and look for the **INSTALLED_APPS** section
![5bc2f2801c226ade60ad52496486ff78_MD5](_resources/3_Project_Structure/5bc2f2801c226ade60ad52496486ff78_MD5.jpg) ![5bc2f2801c226ade60ad52496486ff78_MD5](_resources/3%20-%20Project%20Structure/5bc2f2801c226ade60ad52496486ff78_MD5.jpg)
Add **rest_framework** to **INSTALLED_APPS** Add **rest_framework** to **INSTALLED_APPS**
![c327ae10edcfd245d0ad4cfe787bf9ae_MD5](_resources/3_Project_Structure/c327ae10edcfd245d0ad4cfe787bf9ae_MD5.jpg) ![c327ae10edcfd245d0ad4cfe787bf9ae_MD5](_resources/3%20-%20Project%20Structure/c327ae10edcfd245d0ad4cfe787bf9ae_MD5.jpg)
The next section will then tackle building a REST API with DRF The next section will then tackle building a REST API with DRF

View file

@ -1,5 +1,3 @@
# REST Framework Setup
### API App ### API App
When writing backend APIs, you make changes to your app that may not be compatible with older versions. When writing backend APIs, you make changes to your app that may not be compatible with older versions.
@ -11,20 +9,20 @@ Examples of these include the following;
You should take this into account when building a new project, otherwise users on older versions may encounter errors. You should take this into account when building a new project, otherwise users on older versions may encounter errors.
![3b993b4fb30752dbd22c157c4c852f82_MD5](_resources/4_REST_Framework_Setup/3b993b4fb30752dbd22c157c4c852f82_MD5.jpg) ![3b993b4fb30752dbd22c157c4c852f82_MD5](_resources/4%20-%20REST%20Framework%20Setup/3b993b4fb30752dbd22c157c4c852f82_MD5.jpg)
This lets you allow users on older versions to still use your app (v1) while allowing newer users without any overlap (v2) This lets you allow users on older versions to still use your app (v1) while allowing newer users without any overlap (v2)
We will structure your project in the same manner as above. Create a folder named `api` in your Django project folder besides **config** We will structure your project in the same manner as above. Create a folder named `api` in your Django project folder besides **config**
![e4b384b960e31b256a53775aa6f61ff2_MD5](_resources/4_REST_Framework_Setup/e4b384b960e31b256a53775aa6f61ff2_MD5.jpg) ![e4b384b960e31b256a53775aa6f61ff2_MD5](_resources/4%20-%20REST%20Framework%20Setup/e4b384b960e31b256a53775aa6f61ff2_MD5.jpg)
Create the following files inside the `api` folder Create the following files inside the `api` folder
- `__init__.py` - `__init__.py`
- `urls.py` - `urls.py`
![8357583c43ac252db3811fcc35f21564_MD5](_resources/4_REST_Framework_Setup/8357583c43ac252db3811fcc35f21564_MD5.jpg) ![8357583c43ac252db3811fcc35f21564_MD5](_resources/4%20-%20REST%20Framework%20Setup/8357583c43ac252db3811fcc35f21564_MD5.jpg)
Leave **\_\_init\_\_.py** blank. Instead, open **urls.py** and add the following code Leave **\_\_init\_\_.py** blank. Instead, open **urls.py** and add the following code
```python ```python
@ -48,9 +46,9 @@ urlpatterns = [
Your setup should then look like this Your setup should then look like this
[![8a1e35b34d95be992bd550b32bfe03fa_MD5](_resources/4_REST_Framework_Setup/8a1e35b34d95be992bd550b32bfe03fa_MD5.jpg)](https://bookstack.06222001.xyz/uploads/images/gallery/2024-09/2gZimage.png) [![8a1e35b34d95be992bd550b32bfe03fa_MD5](_resources/4%20-%20REST%20Framework%20Setup/8a1e35b34d95be992bd550b32bfe03fa_MD5.jpg)](https://bookstack.06222001.xyz/uploads/images/gallery/2024-09/2gZimage.png)
[![f9a1c18b83ca805afb4662e6ba43eca2_MD5](_resources/4_REST_Framework_Setup/f9a1c18b83ca805afb4662e6ba43eca2_MD5.jpg)](https://bookstack.06222001.xyz/uploads/images/gallery/2024-09/70bimage.png) [![f9a1c18b83ca805afb4662e6ba43eca2_MD5](_resources/4%20-%20REST%20Framework%20Setup/f9a1c18b83ca805afb4662e6ba43eca2_MD5.jpg)](https://bookstack.06222001.xyz/uploads/images/gallery/2024-09/70bimage.png)
There is no need to include the **api** app in your **INSTALLED\_APPS (config/settings.py)** There is no need to include the **api** app in your **INSTALLED\_APPS (config/settings.py)**

View file

@ -0,0 +1,232 @@
### Authentication with Djoser
Django REST Framework provides basic authentication out of the box, provided with the defaults located in **INSTALLED_APPS** under `settings.py`
To build robust applications however, you will need to more functionality than what it offers;
- Registration
- Account Activation (with activation codes sent via email)
- Password Resets (also sent via email)
- Session expiry with JSON Web Tokens (so that you don't just stay logged in forever)
- and so on...
These features are not built in to DRF, and so we'll have to bring in another package or library for this, [Djoser](https://github.com/sunscrapers/djoser)
To start, run the command `pipenv install djoser djangorestframework-simplejwt`
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/01b6f00e421a060ead2cb4270f9400c2_MD5.jpg)
Add **djoser** and **rest_framework_simplejwt** to **INSTALLED_APPS** under `settings.py`
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/87de24c7f1356d6ccfa6912512afb2a7_MD5.jpg)
You should also add the following code blocks to the end of your `settings.py`.
**REST_FRAMEWORK** will change the authentication type
**DJOSER** provides settings that you will use later on for user registration
```python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
DJOSER = {
'SEND_ACTIVATION_EMAIL': True,
'SEND_CONFIRMATION_EMAIL': True,
'ACTIVATION_URL': 'activation/{uid}/{token}',
}
```
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/61fb00a8563bcf8df7b7084ebd050722_MD5.jpg)
Add the following to your **url_patterns** in `urls.py` file under the **api** app
```python
path('', include('djoser.urls')),
path('', include('djoser.urls.jwt'))
```
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/27ccf2739f021f87445e15e2c12c3de1_MD5.jpg)
Next step, models!
### Note!
If you've gotten this far, congratulations! If you're not familiar with basic and intermediate SQL or Python exercises yet, you may have trouble catching up in the following sections. Please consider learning those first or alongside the sections below.
### User Model
We've added authentication (Djoser) and so we will need to create our own concept of a user.
Models are the heart of backend development (not just Django!). While you may know what a car or a person is, your backend (Django) and your database have no idea how this should be structured.
A person can have the following
- Name
- Age
- Birthday
Cars can have them too! But you get my point.
Django already provides a default [User](https://docs.djangoproject.com/en/5.1/ref/contrib/auth/) model, hidden away from sight. We will be overriding and replacing this with our own.
To start, we will need to create a separate app.
In the previous section, we created a simple folder for the **api** app, this will not work for this step.
Instead, make sure you're inside the Django project directory by doing `cd PROJECT_NAME`, in my case, `cd djangobackend`
We will then create an **accounts** app. Run the command `python manage.py startapp accounts`
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/1acc5ed07b9837584efe9eef7b9f79f0_MD5.jpg)
This will create the **accounts** app
### Note!
The best practice when creating Django apps would be naming them in plural form (Books, Records, Posts)
The Books app can hold
- Books
- Pages
- Chapters
Because of this, there is usually no need to make another app for pages and chapters as mentioned above, unless your app is big enough.
With that out of the way, let's begin creating our User model.
We will be creating our own version of a User based on the default one provided by Django [here](https://docs.djangoproject.com/en/5.1/ref/contrib/auth/)with an age and a birthday
```python
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Some fields are referenced or copied over from AbstractUser
# first_name, last_name, email, username, and password are among a few of these
birthday = models.DateTimeField(null=True)
age = models.IntegerField(null=True)
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
```
If we CTRL + Click on **AbstractUser**, we can take a deeper look under the hood on Django's default User
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/0729283d0df67dfa7dd1a4872e0c65c8_MD5.jpg)
By referencing **AbstractUser** on the User we're creating, we're can skip over creating the other fields a user would have (password, email) and the work that comes with how those work under the hood. This is something you will regularly see with Django and will make developing projects faster.
We'll now need to connect our **accounts** app and the **User** model to our existing project
Open the `admin.py` file in the **accounts** app and add the following code block.
```python
from django.contrib import admin
from .models import CustomUser
# Register your models here.
admin.site.register(CustomUser)
```
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/f8959f3ab5639965cbb7d889c8ca93c2_MD5.jpg)
This will register the model you just created into the Django admin panel (which you will look into later on).
You should then head over to your `settings.py` under the **config** app and add **accounts** to **INSTALLED_APPS**
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/0a19f2ef80c837f84ab52adef345e6d4_MD5.jpg)
Point your authentication to your new **User** model by adding this to `settings.py` under the **config** app
```python
AUTH_USER_MODEL = 'accounts.CustomUser'
```
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/337e74c775664852529ccbda519d08c6_MD5.jpg)
Next, you will need to shuffle some things around
Head back to the **accounts** app and create a `urls.py` file. Add the following code block
```python
from django.urls import path, include
urlpatterns = [
path('', include('djoser.urls')),
path('', include('djoser.urls.jwt')),
]
```
You might notice that this is similar to what we have on the **api** app, we'll be moving these entries to here.
Now that we have those moved over, remove the entries for **djoser.urls** and **djoser.urls.jwt** in `urls.py` under the **api** app
```python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
]
```
Instead, replace what we've removed with
```python
path('accounts/', include('accounts.urls')),
```
Things should look like this after
`urls.py` under **api** app
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/c9c5db2081729eb510dd4571bd3f37c0_MD5.jpg)
`urls.py` under **accounts** app
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/eda08eda23e505477f257e0445938247_MD5.jpg)
With this, your new **accounts** app is now connected.
### Migrations
Django and Django REST Framework (DRF) serves as an interface between your database (MySQL, PostgreSQL, SQLite) and the internet.
It **DOES NOT** hold your data. Rather, it serves as the **backend** to access said data.
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/e5767bab6b1ac8f2e62c8e5beb427992_MD5.jpg)
This is an important distinction to make especially for starters. Exposing your database without a framework such as Django can allow malicious actors to easily make a mess of everything. Everything Django and DRF provides (authentication, middleware, etc.) serves this purpose.
Carrying on, migrations!
Migrations keep track of what types of kinds of things we wish to store. You previously created a **User** model **(accounts app)**.
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/1862970ccde9154f045c5140f0abf05c_MD5.jpg)
To apply these changes to your database, run the command `python manage.py makemigrations`
### Note!
Make sure you're inside the Django project directory! (e.g. `cd PROJECT\_NAME`)
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/d78e3aa3a9bf33079c0545dcb339d0ec_MD5.jpg)
This will create a migration file for your **User** model, which will instruct Django on how to create it inside your SQL database.
Taking a closer look at the newly created migrations file, you can see the following file in `accounts/migrations/0001\_initial.py`
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/0e771b2d300413c7e8ab63081cadfd17_MD5.jpg)
The previous command you just ran (`python manage.py makemigrations`) just translated your **User** model (located in `accounts/models.py`) into instructions which will then be used to create the SQL statements under the hood (e.g. `CREATE TABLE USER (username char, password ...)`)
Migrations are very analogous to sandwiches and burgers in a sense, if you decide to add a **grumpy** attribute to your **User**
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/ff7be23f2bc7166808ee3e0c008c9231_MD5.jpg)
and run `python manage.py makemigrations` again,
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/707051892fcf99a1b4a2eb274603dda0_MD5.jpg)
This will create a second migration file (`0002\_customuser\_grumpy.py`)
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/6b364981137d57591ce32bec05aaa582_MD5.jpg)
When you apply these migrations (which we will do shortly), Django reads each migration file in order, starting off with #1 to create the initial **User** model, and then to step #2 to add the **grumpy** field, which under the hood uses SQL Alter (e.g. `ALTER USER ADD grumpy boolean`).
Django's migrations will also let you know if you make changes to your models that might break things (e.g. removing an already added field when you have records for that already).
This is something you should ideally understand with Django and how it interfaces with your database under the hood.
### Apply Migrations
If you've noticed this error in the previous sections, this is because we haven't applied our migrations yet!
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/a4ed5645c21b33f9823d14533e4c3ef4_MD5.jpg)
With your user schema or template now set up, you should now apply these changes to the database.
Run the command `python manage.py migrate` to apply these changes
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/674a41f71ebe4925d9e40aaee89298bd_MD5.jpg)
This will apply your changes to the database, which by default is SQLite**,** the **db.sqlite3** file.
With that out of the way, running your Django project (`python manage.py runserver 0.0.0.0:8000`) will no longer yield the migration warning.
![image.png](_resources/5%20-%20User%20Setup%20and%20Migrations/cd1442083ceb8430c132da9bfc9b842f_MD5.jpg)
It's always important to apply your migrations before running your app, otherwise you might run into issues.
In the next section, you will be creating your first (superuser) account to access the Django admin panel.

View file

@ -0,0 +1,23 @@
### Admin Panel Overview
By default, all Django apps come with an administrator panel to manage all your models, this includes users too!
![image.png](_resources/6%20-%20Django%20Admin/b7491027aff381ac2c193b31c11750bf_MD5.jpg)
This is accessible via the URL [http://localhost:8000/api/v1/admin/](http://localhost:8000/api/v1/admin/)
In the admin panel, you can do CRUD operations on your models without having to create endpoints. This however is only accessible to administrators so you will have to continue building your API for general access later on. If you have more models, they will show up on the left-hand corner of the site. When selecting a model, such as one for **User**, you can view all instances/records and update, and delete them, hence CRUD (Create Retrieve Update Delete).
![image.png](_resources/6%20-%20Django%20Admin/3b19af469b3157aeaa13d0ed65efa4c4_MD5.jpg)
Right now, you won't be able to access it yet, you haven't made an administrator account after all. This will be outlined in the steps below.
### Note!
The theme above comes from the [django-unfold](https://github.com/unfoldadmin/django-unfold) library. The default design should look the same. You will run into the setup guide django-unfold and other libraries later on, so sit tight!
### Creating an Admin Account
To create a superuser or administrator account. Open a terminal inside your Django project directory and run the command `python manage.py createsuperuser`
![image.png](_resources/6%20-%20Django%20Admin/37fd4cc32b79595791c1a0596156a54b_MD5.jpg)
Be sure to enter a secure password! Django has password validators built-in and may warn you.
![image.png](_resources/6%20-%20Django%20Admin/de9dd7f7b5589adcd14eb7a5358eeaa0_MD5.jpg)

View file

@ -0,0 +1,84 @@
### Overview
An endpoint corresponds to a specific URL in your service. For example, the [localhost:8000/api/v1/books/1](http://localhost:8000/api/v1/books/1) would return the book with the ID=1.
In Django REST Framework, there are some key points you must take note of when writing your own API endpoints
- Database/SQL Table
- Model
- Serializer
- View
- URL
An API endpoint is built from the ground up, starting with the SQL Table. This section assumes you're familiar with SQL (you should be before proceeding with the other chapters!) and the Django Model previously discussed.
![image.png](_resources/7%20-%20Writing%20API%20Endpoints/f6d46eeef4a1644acda573cfd3c673f7_MD5.jpg)
The diagram above is a very rough oversimplification of how Django REST Framework works out of the box
### Model
As mentioned in the previous chapter, the Django model (models.py) defines the object you're intending to keep records of. Whether it be books, students, or menu items, the Django model you create serves as a reference which is then used to populate or create the table in your SQL database.
![image.png](_resources/7%20-%20Writing%20API%20Endpoints/8aafbc6d8b57c1b14e1982b559afc3d6_MD5.jpg)
When called from a serializer, a Django model returns a Python object.
### Serializer
A Django REST Framework serializer takes in a Django model and serializes it into JSON.
In other Python backend frameworks such as [Django Ninja](https://django-ninja.dev/) or [Flask](https://flask.palletsprojects.com), you often skip the serializer process altogether and return values directly.
![image.png](_resources/7%20-%20Writing%20API%20Endpoints/f18ff6ca2e734e8fa7f303466a9dc4fc_MD5.jpg)
Sample Code Snippet from Django Ninja
This is not the case with Django REST Framework.
Serializers define the model used using the class **Meta**. Using a DRF serializer, you can choose to specify which fields to return
![image.png](_resources/7%20-%20Writing%20API%20Endpoints/f5939f9b512e7c4b204129ff4d1b6c44_MD5.jpg)
The serializer above only returns 4 fields (id, username, email, full\_name). Any other fields are omitted such as age, birthday, and so on.
#### Serializer - Validation
In addition to manipulating your model before JSON serialization, DRF serializers allow you to validate fields to ensure proper values are provided.
![image.png](_resources/7%20-%20Writing%20API%20Endpoints/972f5b24877092dabefa35683e9d8a37_MD5.jpg)
In the code snippet above, any fields specified as **required=True** will error out if no value is provided. You don't need to run it through your own checks.
#### Serializer - Custom Hooks
Django REST Framework serializers contain different methods you can use to hook in custom functionalities.
![image.png](_resources/7%20-%20Writing%20API%20Endpoints/55d02092931568fb93eb38d7e0b35fb4_MD5.jpg)
In the code snippet above used for user registration, we can hook custom functions into the validate and create methods which would then be triggered when sending an HTTP POST request that uses our serializer.
The **validate** method is used to verify that a valid password is provided alongside other integrity checks.
The **create** method is also used to ensure that the password and username is set properly**.** In the example above, the user's **is\_active** property is set to **False** in the **create** method to make sure users have to activate their accounts via email.
This is just one of the few use cases for serializer methods, there's an **update** method too alongside others which you can check in the [official documentation](https://www.django-rest-framework.org/api-guide/serializers/).
### Note!
It's important to note that these DRF serializer methods are different from those in Django models. If you choose to use the Django admin panel instead to create your records, the hooks above will not work. The hooks we discuss here only apply to endpoints that use your Django REST Framework serializer.
Django itself provides its own validation through in your models **(models.py)** with methods such as **clean**, **pre\_save**, and **post\_save** with docs found [here](https://docs.djangoproject.com/en/5.1/ref/signals/).
While this may be confusing at first having two approaches to validation, it is important to note that Django and Django REST Framework are separate projects, with one being built on top of the other.
A good use-case for serializer-level validation would be the following;
- An API endpoint for managing (Create, Retrieve, Update, Delete) books for users where you'd need restrictions to stop readers from deleting books they don't own
- An API endpoint for administrators to manage books without restrictions
Each endpoint has their own set of restrictions and requirements so DRF serializer validation would work well here.
Django model validation on the other hand would work better with model field validation,
- Ensure a **User's** **age** matches their **birthday** and if not, throw an error
- Update an **Employee's Payroll** record to increase their **salary** if they are promoted to a higher **position**
The requirements above are irrelevant of the API endpoint used and so model-level validation works best.
Knowing where you should place your validation functions is something you will encounter later on. There's an excellent discussion on [GitHub](https://github.com/encode/django-rest-framework/discussions/7850) which includes view-level validation if you're interested.
If you're just starting off, this isn't something you should be too worried about. Just knowing that the serializer parses to JSON is plenty enough to get started with building CRUD apps.
### Views
Work in progress!

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View file

@ -0,0 +1,16 @@
### Overview
Hosting your own service via the Service Queue project is easy and straightforward as we handle the infrastructure setup for you.
We however provide a network diagram on how it works under the hood for reference.
![Service Queue Hosted.drawio.png](_resources/Hosted%20Services/16f43185b4d19dfcb42d52395a885859_MD5.jpg)
### Project Requirements
We require the following for all projects
- Compatible with ARM64 architecture as our server are a fleet of Orange Pi 5s
- Packaged via Docker with an included `docker-compose.yml`. Traditionally, there are two ways to do this;
- Provide the source code as-is including your provided .env file. The servers will then build the image/container before being served to the public.
- Build Docker image of your service and push it to [Dockerhub](https://hub.docker.com/) in a private repository. You can then give us pull access to download the container so that we serve/run it for your intended use to the public
If you're using a single page application (SPA) framework such as React or Vue, you may opt to skip Docker containerization altogether. We can serve the compiled build as a static site directly. If you're instead using NextJS or a server-side rendered framework, please opt to use Docker in packing up your service instead.

View file

@ -0,0 +1,22 @@
### Overview
You can also opt to use your own servers/devices for hosting with the Service Queue project. Traffic can be relayed through a provided Wireguard VPN to direct subdomain or port traffic to your server
![Service Queue Relayed.drawio.png](_resources/Relayed%20Services/9424cf6e95838d18b4c2a4a5de25bae8_MD5.jpg)
The diagram above serves as reference for the infrastructure setup with relayed services
Game servers can be served via the relay by forwarding the required TCP/UDP ports
### Project Requirements
The following requirements are needed for relayed projects
- A PC, laptop, or similar device
- The device must be compatible with Wireguard VPN
- The device must run 24/7 (or at least run continuously when required for your services to be usable)
- The device must be able to run your services. You will need to ensure system requirements are met (CPU, RAM, and storage).
- A stable internet connection (a poor network connection will result in your subdomains being intermittently unavailable)
You may choose to run your services on bare metal through XAMPP or similar tools when relayed. Docker containerization is not required.
### Alternatives
Cloudflare offers a similar service called [Cloudflare Tunnels](https://www.cloudflare.com/products/tunnel/) though this requires you to have a domain that you have purchased. There is however offer a free offering to try at [try.cloudflare.com](https://try.cloudflare.com/). This URL however is ephemeral (not permanent and may change) and is limited to one domain. This may require more work on your end especially for Frontend/Backend API setups as endpoints may change.
<div class="notranslate" id="bkmrk--1" style="all: initial;"></div>

Some files were not shown because too many files have changed in this diff Show more