- 建立專案
$ mkdir Dinbendon
$ cd Dinbendon
- 建立虛擬環境
$ python3 -m venv venv/Dinbendon
$ source venv/Dinbendon/bin/activate #進入虛擬環境
- 建立專案
$ django-admin startproject Dinbendon
$ python manage.py migrate #第一次使用 初始化Database
- 建立APP
$ python manage.py startapp restaurants
# Dinbendon/Dinbendon
$ vi settings.py
INSTALLED_APPS = (
...
'django.contrib.staticfiles',
'restaurants', #新增這行
)
設定view.py
#Dinbendon/restaurants/views.py
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from restaurants.models import Restaurant, Food
def menu(request):
restaurants = Restaurant.objects.all()
return render_to_response('menu.html',locals())
設定urls.py
#
...
from restaurants.views import menu
urlpatterns = [
...
url(r'^menu/$', menu),
]
- 建立model
#Dinbendon/restaurants/models.py
from django.db import models
class Restaurant(models.Model):
name = models.CharField(max_length=20)
phone_number = models.CharField(max_length=15)
address = models.CharField(max_length=50, blank=True)
def __unicode__(self):
return self.name
class Food(models.Model):
name = models.CharField(max_length=20)
price = models.DecimalField(max_digits=3,decimal_places=0)
comment = models.CharField(max_length=50, blank=True)
is_spicy = models.BooleanField()
restaurant = models.ForeignKey(Restaurant)
def __unicode__(self):
return self.name
- 同步資料表
$ python manage.py makemigrations restaurants
- 透過shell新增資料
練習透過Shell的方式新增資料,但還是可以透過admin的頁面新增比較快,這邊算是一個練習.
$ python manage.py shell
>>> from restaurants.models import Restaurant, Food
>>> r1 = Restaurant(name='隔壁老王滷肉飯', phone_number='02-12345678', address='天龍國天龍區天龍路1 號')
>>> r1
<Restaurant: Restaurant object>
建立一個模型物件記得匯入app中models.py裡的模型,並以參數(模型中個資料欄位的名稱)將之實體化即可,如上例r1是一個Restaurant物件,也就是資料表中的一筆資料,不過切記,目前該筆資料尚未被寫入資料庫中。
將模型物件(資料)寫入資料庫,利用save
方法可以將資料寫入資料庫,等我們關閉shell後,該筆資料仍然會存在:
>>> r1.save()
模型的objects.all()
方法可以從模型對應的資料表中取得所有的資料,並會回傳一個對應的模型物件清單(list of model objects)
objects.get
方法會回傳一個模型物件,也就是一筆資料,如果回傳的是多筆或是查詢結果失敗(空),都會引發例外,這可以利用try/expect
來捕獲並處理。
過濾查詢
利用屬性名+__contains=值
可以搜尋該屬性包含值的資料(包含的意思表示不需全等,部分有符合即可)
>>> restaurants = Restaurant.objects.filter(name__contains='餐廳')
[<Restaurant: 古意得餐廳>]
排序查詢
QuerySet是依照id排序的,利用objects管理器的order_by方法,可以自行指定資料欄位進行排序:
>>> r = Restaurant.objects.get(name='古意得餐廳')
>>> f1 = Food(name='宮保雞丁', price=120, comment='超級辣', is_spicy=True, restaurant = r)
>>> f1.save()
>>> f2 = Food(name='炒青菜', price=85, comment='每日不同', is_spicy=False, restaurant = r)
>>> f2.save()
>>> Food.objects.all()
[<Food: 宮保雞丁>, <Food: 炒青菜>]
>>> Food.objects.order_by('price')
[<Food: 炒青菜>, <Food: 宮保雞丁>]
order_by的參數是字串,不要誤植為order_by(price)了。
Ex.
>>> Food.objects.order_by('price','name') # 先排price再排name
>>> Food.objects.order_by('-price') # 反向排序
任何一個QuerySet都能夠繼續以order_by、filter、get等方法進行查詢:
>>> Food.objects.order_by('price').filter(is_spicy=True).get(name__contains='宮保')
<Food: 宮保雞丁>
更新與刪除資料庫數據
>>> food = Food.objects.get(name='宮保雞丁')
>>> food.price = 200
>>> food.save()
or
>>> Food.objects.filter(name='宮保雞丁').update(price=200)
1
update是QuerySet的方法,無法作用在單獨物件上,所以我們要偷偷用點技巧,使用filter來過濾出只含有宮保雞丁的QuerySet。
刪除資料可以用delete方法
>>> f = Food.objects.get(name='宮保雞丁')
>>> f.delete()
>>> Food.objects.all()
[<Food: 炒青菜>]
>>> Food.objects.all().delete()
[]
- 顯示app
#.../restaurants/templates/menu.html
<!doctype html>
<html>
<head>
<title> Menu </title>
<meta charset='utf-8'>
</head>
<body>
{% for r in restaurants %}
<h2>{{ r.name }}</h2>
{% if r.food_set.all %}
<p>本餐廳共有{{ r.food_set.all|length }}道菜</p>
<table>
<tr>
<th>菜名</th>
<th>價格</th>
<th>註解</th>
<th>辣不辣</th>
</tr>
{% for food in r.food_set.all %}
<tr>
<td> {{ food.name }} </td>
<td> {{ food.price }} </td>
<td> {{ food.comment }} </td>
<td> {% if food.is_spicy %} 辣 {% else %} 不辣 {% endif %} </td>
</tr>
{% endfor %}
</table>
{% else %}
<p>本餐廳啥都沒賣</p>
{% endif %}
{% endfor %}
</body>
</html>
- Admin
建立admin的資料表, 驗證模型
$ python manage.py check
System check identified no issues (0 silenced).
建立superuser, 設定帳號密碼
$ python manage.py createsuperuser
註冊model, 透過admin.site.register
方法,便可以在admin介面中新增、檢視、編輯、刪除我們模型中的資料。
#.../restaurants/admin.py
from django.contrib import admin
from restaurants.models import Restaurant, Food
class RestaurantAdmin(admin.ModelAdmin):
list_display = ('name', 'phone_number', 'address')
search_fields = ('name',)
class FoodAdmin(admin.ModelAdmin):
list_display = ('name', 'restaurant', 'price')
list_filter = ('is_spicy',)
fields = ('price','restaurant')
ordering = ('-price',)
admin.site.register(Restaurant)
admin.site.register(Food)
- 數據提交訊息 - GET與POST
加入一個歡迎頁面
# .../Dinbendon/urls.py
# 以上略...
from Dinbendon.views import welcome
from restaurants.views import menu
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^menu/$', menu),
url(r'^welcome/$', welcome),
)
然後準備一個視圖給要回應的頁面
#/Deinbendon/templates/welcome.html
<html>
<head>
<title> Welcome </title>
</head>
<body>
<form action="" method="get">
<label for="user_name">您的名字</label>
<input id="user_name" type="text" name="user_name">
<input type="submit" value="進入網站">
</form>
</body>
</html>
在表單中,我們選用了GET方法,這表示我們提交表單後,表單內容中的鍵值對會形成查詢字符付在請求頁面的後面。
如果user_name欄位中的名字填的是datou,表單提交後,會發出一個請求,這個請求的路徑是:
http://網域名/welcome/?user_name=datou
而user_name=datou
這個鍵值配對會被存入request.GET
中,用request.GET['user_name']
可以存取到’dokelung’(字串型態)這個值。
最後是撰寫對應的view function:
#.../Dinbendon/views.py //自行新增
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
def welcome(request):
if 'user_name' in request.GET:
return HttpResponse('Welcome!~'+request.GET['user_name'])
else:
return render_to_response('welcome.html',locals())
- 顯示welcome.html
要讓Django知道這個template並不是在app的資料夾中,不然runserver的話,會一直出現TemplateDoesNotExist
. 要對settings.py進行修改.
import os
PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))
...
#set DIRS in TEMPLATES setting var:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(PACKAGE_ROOT, 'template')], #新增這行.
'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',
],
},
},
]
參考:
https://github.com/uranusjr/django-tutorial-for-programmers
http://stackoverflow.com/
沒有留言:
張貼留言