# **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 ``` * 開啟虛擬機就會像這樣 ![螢幕擷取畫面 2024-03-15 201610](https://hackmd.io/_uploads/rJnZ6nW0T.png) * 安裝 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}}&ensp; {% 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 ```