# **Django install**
> django 官網 : https://www.djangoproject.com/start/
> 別人的 hackmd : https://hackmd.io/@peterju/B12HQdsFO
* 安裝 python 並加入 path : https://www.python.org/downloads/windows/
* 安裝 vscode : https://code.visualstudio.com/
* python 3.6.6 加入 path
* cmd : `python --version` 檢查有沒有成功
* 安裝 pip : `python get-pip.py`
* cmd : `pip --version` 檢查有沒有成功
* 安裝虛擬機
```
//下載虛擬機
python -m pip install virtualenv
//打開權限
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
//創建虛擬機 myenv 是虛擬機的名字, 可以自己改
python -m venv myenv
//開啟虛擬機
myenv\Scripts\Activate
//關閉虛擬機
deactivate
```
* 開啟虛擬機就會像這樣

* 安裝 django (一樣要在虛擬機模式下)
```
//下載 django
pip install django
//確認版本
django-admin --version
//建立 project, Orange 是專案名稱可以自己改
django-admin startproject Orange
```
* 每個檔案的用途去看這邊 : https://ithelp.ithome.com.tw/articles/10199733
* 到 Orange\settings.py 改語言和時區
```
LANGUAGE_CODE = 'en-TW'
TIME_ZONE = 'Asia/Taipei'
```
* 啟動 web server
```
py manage.py runserver
```
# **Project Setting**
* 創建 app : myapp
```
//創建 app : myapp
python manage.py startapp myapp
```
* 更改 Orange/setting.py
```
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', # 加入 myapp
]
```
* 建立靜態檔案, 模板
```
md templates
md static
md static\images
md static\css
md static\js
md static\plugins
```
* 更改 Orange/setting.py 公開 templates 路徑讓所有 apps 都可以調用
```
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates"], #加入templates路徑
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
```
* 將下面這行加入 Orange/settings.py, 公開 static 路徑
```
import os
STATICFILES_DIRS=[
os.path.join(BASE_DIR,"static")
]
```
---
下面隨個人喜好設定, 可做可不做
* 到官網下載 bootstrp : https://getbootstrap.com/docs/5.3/getting-started/download/
* 將檔案複製到 Orange/static/plugins
* 加入 <link> 到 html 檔案, 連結到 bootstrp 檔案
<!DOCTYPE html>
```
<link rel="stylesheet" href="/static/plugins/bootstrap-5.3.3-dist/css/bootstrap.css">
```
* 也可以使用網頁連結, 這樣就不需要下載 bootstrp 檔案, 但沒網路會跑不出來
```
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
```
# **Simple Creation**
## Example 1 : Views html 溝通, URL 映射
* Orange/urls.py
```
from django.contrib import admin
from django.urls import path
from myapp import views as myapp_views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', myapp_views.index),
path('index2/', myapp_views.index2),
path('hello/<name>', myapp_views.hello),
]
```
* Orange/templates/index.html
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{name}}</title>
</head>
<body>
<p>{{name}}</p>
<p>{{age}}</p>
</body>
</html>
```
* Orange/myapp/views.py
```
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return render(request, "index.html",{
"name":"Orangebaby",
"age":"20"
})
def hello(request, name):
return HttpResponse("Hello " + name)
def index2(request):
context={}
context["age"]="20"
context["name"]="Orangebaby"
return render(request, "index.html", context)
#index and index2 兩種方法相同
```
* 嘗試打開 http://127.0.0.1:8000/index/, http://127.0.0.1:8000/index2/ views 兩種不同的傳值方法, 效果相同
* hello/ 後面的字, 會直接接入網頁內, http://127.0.0.1:8000/hello/Orange
## Example 2 : 引入 static 資料
* 下載圖片 : https://www.pinterest.com/pin/281543723295792/, 放入 Orange/static/images
* 將 staic 檔案資料載入 index.html
```
<body>
{%load static%}
<img src="{%static 'images/ppp.jpg'%}" height="500">
</body>
```
## Example 3 : 模板繼承
* 將 base.html 整個繼承到 index.html, 其中只需定義 block 的資料即可
* index.html
```
{% extends "base.html" %}
{% block mainbody %}
<p> Orange </p>
{% endblock mainbody %}
{% block food %} apple {% endblock food %}
```
* base.html
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Orange</title>
</head>
<body>
<p>Hi</p>
{% block mainbody %}
{% endblock mainbody %}
<p>我想吃 {% block food %}{% endblock food %}</p>
</body>
</html>
```
## Example 3 : dict, list, if/else, for loop
* myapp/views.py
```
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
context={}
context["name"] = "Orange"
views_list = ["Apple", "Banana", "Cheese"]
context["list"] = views_list
views_dic = {"food":"Apple","color":"red","number":10}
context["dict"] = views_dic
lucky_number = 80
context["lucky_number"] = lucky_number
return render(request, "index.html",context)
```
* index.html
```
<body>
{# list #}
<h1><b>list section</b></h1>
<p>{{ list }}</p>
<p>{{ list.0 }}</p>
<p>{{ list.1 }}</p><p>{{ list.2 }}</p>
{# dict #}
<h1><b>dict section</b></h1>
<p>{{ dict }}</p>
<p>{{ dict.food }}</p>
<p>{{ dict.color }}</p>
<p>{{ dict.number }}</p>
{# if/else #}
<h1><b>if/else section</b></h1>
<p>
{% if lucky_number >= 100 %}
You are lucky.
{% elif lucky_number >= 50 %}
You are normal.
{% else %}
You are poor
{% endif %}
</p>
{# for loop #}
<h1><b>for loop section</b></h1>
<p>
{% for food in list %}
{{food}}
{% endfor %}
<br>
{% for key, value in dict.items %}
{{key}} : {{value}} 
{% endfor %}
<br>
{% for i in emptylist %}
i
{% empty %}
This list is empty
{% endfor %}
</p>
</body>
```
## Example 4 : 自定義標籤
* Orange/setting.py 新增 libraries
```
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates"],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'libraries':{ #新增 libraries
'my_def':'templates.my_def', #自定義函數的位置
}
},
},
]
```
* Orange/templates/my_def.py
```
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.simple_tag
def add(a, b, c):
return a+b+c
@register.simple_tag
def input():
temp = f'''
<ul class="dropdown-menu position-static d-grid gap-1 p-2 rounded-3 mx-0 shadow w-220px" data-bs-theme="light">
<li><a class="dropdown-item rounded-2 active" href="#">Action</a></li>
<li><a class="dropdown-item rounded-2" href="#">Another action</a></li>
<li><a class="dropdown-item rounded-2" href="#">Something else here</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item rounded-2" href="#">Separated link</a></li>
</ul>
'''
return mark_safe(temp)
```
* Orange/templates/index.html
```
<!DOCTYPE html>
<html lang="en">
{% include "header.html" %}
<body>
{% load my_def %}
<h1> {% add 10 20 30 %} </h1><br><br>
{% input %}
</body>
</html>
```
* Orange/templates/header.html
```
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{name}}</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-5.3.3-dist/css/bootstrap.css">
</head>
```
# **DataBase**
* 下載 Mysql
```
pip install mysqlclient
```
* 變更 Django 使用的資料庫
```
DATABASES = { #記得下面都要填仔細, 不然 web 會跑不起來
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'your_database_name',
'USER': 'your_mysql_username',
'PASSWORD': 'your_mysql_password',
'HOST': 'localhost',
'PORT': '3306',
}
}
```
* 內建 APP 所需之資料表
```
py manage.py migrate
```
* 更新 myapp/model.py, 變更資料模型 (直接決定資料庫的模型)
```
from django.db import models #This is example
from django.utils import timezone
# Create your models here.
class student(models.Model):
SEX_CHOICES = [
('M', '男'),
('F', '女'),
]
cName = models.CharField('姓名',max_length=20, null=False)
cSex = models.CharField('性別',max_length=1, choices=SEX_CHOICES, default='', null=False)
cBirthday = models.DateField('生日',null=False)
cEmail = models.EmailField('Email',max_length=100, blank=True, default='')
cPhone = models.CharField('手機',max_length=50, blank=True, default='')
cAddr = models.CharField('地址',max_length=255, blank=True, default='')
last_modified = models.DateTimeField('最后修改日期', auto_now = True)
created = models.DateTimeField('保存日期',default = timezone.now)
def __str__(self):
return self.cName
```
* 將模型的異動產生 migrations 遷移檔
```
py manage.py makemigrations myapp
```