一連練習了一些Django的應用,在這邊在整理以及複習一下前幾篇使用過的一些東西,加深印象.
開啟專案
$ django-admin startproject projectName
開啟專案後執行runserver
$ python manage.py migrate #同步資料庫
$ python manage.py runserver
Validating models...
0 errors found
Django version 1.8.2, using settings 'xxx.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Admin模組
- 確認settings.py,INSTALLED_APPS的
django.contrib.admin
前面的#
註解拿掉 - 確認urls.py,
from django.contrib import admin
以及admin.autodiscover()
兩行的註解拿掉,然後在urlpatterns
的最後一行url(r'^admin/', include(admin.site.urls))
的註解也拿掉. - 執行
python manage.py createsuperuser
,設定帳號密碼. - 執行runserver,就可以在
http://192..../admin
看到以下畫面.
建立App
$ python manage.py startapp APP
專案裡建立一個叫做APP
的資料夾.
Model
負責處理跟資料庫相關的事情.使用 Django Model 的來操作資料庫的優點之一,就是資料庫轉換相當方便,假設要從SQLite換到MySQL,雖然在資料庫中有些欄位的定義不一樣,但在Django Model中,程式碼幾乎不用修改就可以無痛的把資料庫整個換掉了。
Ex.
# APP/models.py
from django.db import models
# Create your models here.
class Profile(models.Model):
name = models.CharField(max_length = 50)
age = models.IntegerField()
tel = models.CharField(max_length = 30)
address = models.CharField(max_length = 100)
email = models.EmailField()
def __str__(self):
return self.name
- CharField – 字串欄位,適合像 title、location 這種有長度限制的字串。
- TextField – 合放大量文字的欄位
- URLField – URL 設計的欄位
- DateTimeField – 日期與時間的欄位,使用時會轉成 Pythondatetime型別
專案的settings.py中,加入App. 這樣Django專案就知道我們有這個App了.
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'author',
)
同步資料庫
$ python manage.py migrate
#migrate 指令會根據INSTALLED_APPS的設定,按照 app 順序建立或更新資料表,將你在 models.py 裡的更新跟資料庫同步。
執行syncdb之後,Django幫你建立了一個叫做author_profile的表格。
$ python manage.py syncdb
Django shell
可以讓你直接透過指令來操作物件,不用寫SQL語法,一樣可以做到資料的Create (新增)、Read (讀取)、Update (修改)、Delete (刪除) 功能。
$ python manage.py shell
#Create
>>> from trips.models import Post
>>> Post.objects.create(title='My First Trip', content='肚子好餓,吃什麼好呢?', location='台北火車站')
<Post: Post object>
#Read
# XXX/models.py
from django.db import models
class Post(models.Model):
...
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self): #記得加這行
return self.title
>>> Post.objects.all()
[<Post: My First Trip>]
#Update
#想修改資料時,可以使用 update 更新一筆或多筆資料:
>>> posts.update(location='捷運大安站')
2 #回傳的數字 2 指的是已被更新的資料筆數。
>>> posts[0].location
'捷運大安站'
>>> posts[1].location
'捷運大安站'
#Delete
>>> posts.delete()
View
處理 request 的流程如下:
- 瀏覽器送出 HTTP Request
- Django 依據 URL Conf 分配至對應的 View
- View 進行資料庫的操作或其他運算,並回傳 Http Response 物件
- 瀏覽器依據 HTTP Response,顯示網頁畫面
view 其實是一個 function,處理 HttpRequest 物件,並回傳 HttpResponse 物件,大致說明如下:
- 會收到HttpRequest 物件參數: Django 從網頁接收到 request 後,會將 request 中的資訊封裝產生一個 HttpRequest 物件,並當成第一個參數,傳入對應的 view function。
- 需要回傳HttpResponse物件:
HttpResponse
物件裡面包含:
- HttpResponse.content
- HttpResponse.status_code …等
設定View主要有兩個步驟:
1. 設定urls.py
2. 撰寫視圖函式
設定urls.py
url(r'^here/$', here)
就是告訴Django,看到網域後面出現/here/就去call views.py
裡面的function here
來動作.
# /mysite/urls.py
from views import here # 從views.py中匯入here這個function
urlpatterns = [
url(r'^here/$', here), # 加入此行
url(r'^admin/', include(admin.site.urls)),
]
撰寫視圖函式
#/mysite/views.py
from django.http import HttpResponse
def here(request):
return HttpResponse('Hello World!')
以上程式在做的事就是:
- 從 django.http 模組中引用 HttpResponse 類別
- 宣告 here 這個 View
- 當 here 被呼叫時,回傳包含字串 Hello World! 的 HttpResponse 物件。
網址設定
URL Conf
- 通常定義在urls.py
- 是一連串的規則 (url pattern)
- Django 收到 request 時,會一一比對 URL Conf 中的規則,決定要執行哪個 view function
在Django的網址設定是交給一個叫做urls.py的檔案在管理(其實不限定只有一個,也可以多個/模組化的設定).
from django.conf.urls import include, url
from django.contrib import admin
from stores.views import home, store_list, store_detail
urlpatterns = [
url(r'^$', home, name='home'),
url(r'^admin/', include(admin.site.urls)),
url(r'^store/$', store_list, name='store_list'),
url(r'^store/(?P<pk>\d+)/$', store_detail, name='store_detail'),
]
urls.py
的主要功能,就是設定”當遇到某個網址的request的時候,請找指定的App裡的View的action處理”。
Ex.
url(r'^here/$', here),
r'^here/$'
:是Python中正規表達式的寫法,^號代表配對開始,$號代表配對結束,所以該表達式代表的是網域後的字串要“完全”等於/here/才算配對成功
here前面並沒有寫出/,這是因為Django預設會幫你加上這個slash。
以上程式透過 url
() function 傳入兩個參數 regex
,view
:
url(regex,view)
- regex – 定義的 URL 規則
- 規則以 regular expression 來表達
- r’^here/$’ 代表的是 here/ 這種 URL
- view – 對應的 view function
- 指的是 here 這個 view
'trips.views.hello_world'
– trips 裡的 views.py 中的 hello_world() function
url(r'^$', 'bookstore.book.views.index'),
表示「當遇到網址後面沒接東西的時候(也就是大家俗稱的”首頁”),請找book/views.py裡面的index方法處理」,前面的bookstore是整個專案的名稱。
url(r'^books/(?P<book_id>\d+)/$', 'bookstore.book.views.detail'),
意思是假設遇到http://127.0.0.1:8000/books/100
的網址候,100會被當做book_id傳給book/views.py的detail方法當做參數。
def home(request):
return render(request, 'home.html')
在views.py裡的方法,通常我們會稱它叫做action,每個action方法的第一個參數,一定都是http request,每個action的回傳值,一定要是一個HttpResponse。views.py在一般的MVC架構裡,大概就是Controller之類的角色。
Template
Django雖然是Python寫的,但不同的是不可以在Template
裡寫Python的程式碼,你在Template只能用Template提供的API,以及一些filter跟tag(不管是內建或是自己寫的)。
shortcuts
: 用loader把template抓出來,再把結果render出來,變成一行render
就搞定
#第一件事情先建立資料夾.
$ mkdir templates
from django.shortcuts import render
def home(request):
return render(request, 'home.html')
這次傳入的參數有:
- request – HttpRequest 物件
- template_name – 要使用的 Template
- dictionary – 包含要新增至 Template 的變數
Render :產生 HttpResponse 物件。
render(request, template_name, dictionary)
Ex.
from django.shortcuts import render
def hello_world(request):
return render(request,
'hello_world.html',
{'current_time': datetime.now()})
Template API
Ex.
{% for store in stores %}
<div class="store">
<h2><a href="{% url 'store_detail' pk=store.pk %}">{{ store.name }}</a></h2>
<p>{{ store.notes }}</p>
</div>
{% endfor %}
這些程式碼,是可以寫在.html裡的,反正到時候Django會把.html當做Template讀出來之後再解析它,最後把內容render給使用者看。
在Template裡,如果看到
{% .. %}
的,表示它是一個邏輯運算或是語法,通常不會有輸出值;而看到{{ .. }}
的話,就是會把裡面的值吐出來放HTML裡的。
#forloop
{% for <element> in <list> %}
...
{% endfor %}
#if...else
{% if condition %}
...
{% else %}
...
{% endif %}
Filters
在Django中”資料呈現”的工作,只要交給Template的Filter來做就可以了.Template的Filter有點像在Linux系統上的pipe
,就是可以透過|
符號,把前面的資料丟給下一個執行,直到最後結束為止,filter在用的時候,|
的左右不可以有空白,不然會直接出現TemplateSyntaxError
。
{{<variable_name>|<filter_name>:<filter_arguments>}}
- < variable_name > – 變數名稱
- < filter_name > – filter 名稱,例如add, cut等等
- < filter_arguments > – 要傳入 filter 的參數
Ex.
#將 created_at 時間,以 年 / 月 / 日 的形式顯示:
{{ post.created_at|date:"Y / m / d" }}
想要在最一開始列出食物的總項目數量的話,可以借助過濾器length使用|
來接收前面的資料並做處理.
Model->Template
資料也可以從admin後台
或Shell
來做新增/修改/刪除/更新。
資料庫透過Store類別
給取出來,然後再以dictionary型式傳給render
. 就可以將值傳給上述的Ex
中,讓Template裡就可以取用得到Store這個變數。
def store_list(request):
stores = Store.objects.all()
return render(request, 'store_list.html',{'stores': stores})
def store_detail(request, pk):
try:
store = Store.objects.get(pk=pk)
except Store.DoesNotExist:
raise Http404
return render(request, 'store_detail.html',{'store': store})
Http404,意思就是說如果資料庫裡面找不到這筆資料的話,就會直接丟出HTTP 404的畫面。
Regex
Django 的 URL 是一個 Regular Expression (Regex)。Regular expression 可用來描述一個字串的樣式。
(?P<id>\d+)
- \d 代表一個阿拉伯數字。
+
代表「一個以上」。
所以 \d+ 代表一個以上的阿拉伯數字,例如「0」、「99」、「12345」。可是像「8a」就不符合,因為「a」不是數字。(?P<id>)
代表「把這一串東西抓出來,命名為 id。
所以 (?P<id>\d+)
代表:抓出一個以上阿拉伯數字,並把抓出來的東西取名為 id。
參考:
https://docs.djangoproject.com/en/1.8/
http://blog.eddie.com.tw/
http://djangogirlstaipei.gitbooks.io/django-girls-taipei-tutorial/content/django/templates.html
沒有留言:
張貼留言