###### tags: `jptw` `thesis` `technology` `python` `django`
# Notes for Django
> Tutorial:
> [1] [Python 3 Tutorial 第八堂(2)建立 App 與模型](https://openhome.cc/Gossip/CodeData/PythonTutorial/AppModelPy3.html)
## Folder Structure
```
mysite
├── manage.py
├── /mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
└── /polls
├── __init__.py
├── admin.py
├── apps.py
├── migrations/
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
```
## Setup Django Project
### Install
```shell
$ pip3 install Django
```
### Start Project
```shell
// create
$ django-admin startproject mysite
// run
$ python manage.py runserver
```
### Create App
```shell
$ python manage.py startapp polls
```
> Tutorial:
> [1] [编写你的第一个 Django 应用,第 1 部分](https://docs.djangoproject.com/zh-hans/3.1/intro/tutorial01/)
## Models
### on_delete
`models.CASCADE` 對應資料一併刪除
> Ref: [Day6 : 資料庫的創建 - Models](https://ithelp.ithome.com.tw/articles/10200181)
### unique_together
Multiple fields as unique key
```python
from django.db import models
class Post(models.Model):
user= models.ForeignKey(User)
title= models.ForeignKey(Post)
date= models.DateTimeField(auto_now= True)
def __str__(self):
return str(self.user) + ':' + str(self.post)
class Meta:
unique_together = ("user", "title")
```
> Ref: [How to Make Fields of a Database Table Unique Together in Django](http://www.learningaboutelectronics.com/Articles/How-to-make-fields-of-a-database-table-unique-together-in-Django.php)
### Filter
```python
from operator import and_
from django.db.models import Q
categories = ['holiday', 'summer']
# Method 1
res = Photo.filter(reduce(and_, [Q(tags__name=c) for c in categories]))
# Method 2
res = Photo.filter(Q(tags__name='holiday') & Q(tags__name='summer'))
```
> Ref: [Django filter queryset __in for *every* item in list](https://www.semicolonworld.com/question/43842/django-filter-queryset-in-for-every-item-in-list)
### Serializer
```python
from rest_framework import serializers
serializer = PostSerializer(data=data)
serializer.is_valid()
```
> Ref: [Django REST Framework | Serializers](https://www.django-rest-framework.org/api-guide/serializers/)
## Command
### Structure
```
polls/
__init__.py
models.py
management/
commands/
_private.py
closepoll.py
tests.py
views.py
```
### HowToUse
closepoll.py
```python
from django.core.management.base import BaseCommand, CommandError
from polls.models import Question as Poll
class Command(BaseCommand):
help = 'Closes the specified poll for voting'
def add_arguments(self, parser):
parser.add_argument('poll_ids', nargs='+', type=int)
def handle(self, *args, **options):
...
self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))
```
Terminal
```shell
$ python manage.py closepoll <poll_id>
```
> Tutorial:
> [1] [编写自定义 django-admin 命令](https://docs.djangoproject.com/zh-hans/3.1/howto/custom-management-commands/)
> [2]* [How to Create Custom Django Management Commands](https://simpleisbetterthancomplex.com/tutorial/2018/08/27/how-to-create-custom-django-management-commands.html)
> [3] [django-admin and manage.py](https://docs.djangoproject.com/en/3.0/ref/django-admin/)
## Settings
### Environment
Installation
```cmd
$ pip install django-environ
```
`.env` file
```python
DEBUG=FALSE
SECRET_KEY=your-secret-key
DATABASE_URL=psql://urser:un-githubbedpassword@127.0.0.1:8458/database
SQLITE_URL=sqlite:///my-local-sqlite.db
CACHE_URL=memcache://127.0.0.1:11211,127.0.0.1:11212,127.0.0.1:11213
REDIS_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient&password=ungithubbed-secret
```
> Ref: [Welcome to Django-environ’s documentation!](https://django-environ.readthedocs.io/en/latest/)
### Database
```python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {'charset': 'utf8mb4'},
(...)
```
SQL command
```mysql
ALTER DATABASE el CHARACTER SET utf8 COLLATE utf8_general_ci
```
`.env` file
```python
DATABASE_URL = mysql://user:pass@localhost/django?CHARSET=utf8mb4
```
> Ref:
> [1] [Make MySQL backend default to utf8mb4 encoding](https://code.djangoproject.com/ticket/18392)
> [2] [Checks | Django-MySQL](https://django-mysql.readthedocs.io/en/latest/checks.html#django-mysql-w003-utf8mb4)
> [3] [Collation and charset?](https://github.com/joke2k/django-environ/issues/96)
### CORS
```python
INSTALLED_APPS = [
...
'corsheaders',
...
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
CCORS_ALLOWED_ORIGINS = [
"https://example.com",
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:9000"
]
```
> Ref:[django-cors-headers 3.5.0](https://pypi.org/project/django-cors-headers/)
## Database
> Ref: [Notes for Database | Cosine](/@ahglab/thesis-tech-db)
## Routers
```python
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from main import views
router - DefaultRouter()
router.register(r'main', views.mainViewSet)
urlpatterns = [
path('', include(router.urls)),
]
```
> Ref: [Tutorial 6: ViewSets & Routers](https://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/)