原生sql和python的orm代碼對比css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
#sql中的表
#建立表:
CREATE TABLE employee(
id
INT
PRIMARY KEY auto_increment ,
name VARCHAR (
20
),
gender BIT default
1
,
birthday DATA ,
department VARCHAR (
20
),
salary DECIMAL (
8
,
2
) unsigned,
);
#sql中的表紀錄
#添加一條表紀錄:
INSERT employee (name,gender,birthday,salary,department)
VALUES (
"alex"
,
1
,
"1985-12-12"
,
8000
,
"保潔部"
);
#查詢一條表紀錄:
SELECT
*
FROM employee WHERE age
=
24
;
#更新一條表紀錄:
UPDATE employee
SET
birthday
=
"1989-10-24"
WHERE
id
=
1
;
#刪除一條表紀錄:
DELETE FROM employee WHERE name
=
"alex"
#python的類
class
Employee(models.Model):
id
=
models.AutoField(primary_key
=
True
)
name
=
models.CharField(max_length
=
32
)
gender
=
models.BooleanField()
birthday
=
models.DateField()
department
=
models.CharField(max_length
=
32
)
salary
=
models.DecimalField(max_digits
=
8
,decimal_places
=
2
)
#python的類對象
#添加一條表紀錄:
emp
=
Employee(name
=
"alex"
,gender
=
True
,birthday
=
"1985-12-12"
,epartment
=
"保潔部"
)
emp.save()
#查詢一條表紀錄:
Employee.objects.
filter
(age
=
24
)
#更新一條表紀錄:
Employee.objects.
filter
(
id
=
1
).update(birthday
=
"1989-10-24"
)
#刪除一條表紀錄:
Employee.objects.
filter
(name
=
"alex"
).delete()
|
建立名爲book的app,在book下的models.py中建立模型:html
1
2
3
4
5
6
7
8
9
10
11
12
|
from
django.db
import
models
# Create your models here.
class
Book(models.Model):
id
=
models.AutoField(primary_key
=
True
)
#若是表裏面沒有寫主鍵,表裏面會自動生成一個自增主鍵字段,叫作id字段,orm要求每一個表裏面必需要寫一個主鍵
title
=
models.CharField(max_length
=
32
)
#和varchar(32)是同樣的,32個字符
state
=
models.BooleanField()
pub_date
=
models.DateField()
#必須存這種格式"2018-12-12"
price
=
models.DecimalField(max_digits
=
8
,decimal_places
=
2
)
#max_digits最大位數,decimal_places小數部分佔多少位
publish
=
models.CharField(max_length
=
32
)
|
接下來要建立對應的數據,鏈接上對應的數據庫,而後執行建立表的命令,翻譯成相應的sql,而後到數據庫裏面執行,從而建立對應的表。多了一步orm翻譯成sql的過程,效率低了,可是沒有太大的損傷,還能忍受,當你不能忍的時候,你能夠本身寫原生sql語句,通常的場景orm都夠用了,開發起來速度更快,寫法更貼近應用程序開發,還有一點就是數據庫升級或者變動,那麼你以前用sql語句寫的數據庫操做,那麼就須要將sql語句所有修改,可是若是你用orm,就不須要擔憂這個問題,無論是你從mysql變動到oracle仍是從oracle更換到mysql,你若是用的是orm來搞的,你只須要修改一下orm的引擎(配置文件裏面改一些配置就搞定)就能夠了,你以前寫的那些orm語句仍是會自動翻譯成對應數據庫的sql語句。 python
每一個字段有一些特有的參數,例如,CharField須要max_length參數來指定VARCHAR
數據庫字段的大小。還有一些適用於全部字段的通用參數。 這些參數在文檔中有詳細定義,這裏咱們只簡單介紹一些最經常使用的:mysql
更多字段:jquery
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
'''
<1> CharField
字符串字段, 用於較短的字符串.
CharField 要求必須有一個參數 max_length, 用於從數據庫層和Django校驗層限制該字段所容許的最大字符數.
<2> IntegerField
#用於保存一個整數.
<3> FloatField
一個浮點數. 必須 提供兩個參數:
參數 描述
max_digits 總位數(不包括小數點和符號)
decimal_places 小數位數
舉例來講, 要保存最大值爲 999 (小數點後保存2位),你要這樣定義字段:
models.FloatField(..., max_digits=5, decimal_places=2)
要保存最大值一百萬(小數點後保存10位)的話,你要這樣定義:
models.FloatField(..., max_digits=17, decimal_places=10) #max_digits大於等於17就能存儲百萬以上的數了
admin 用一個文本框(<input type="text">)表示該字段保存的數據.
<4> AutoField
一個 IntegerField, 添加記錄時它會自動增加. 你一般不須要直接使用這個字段;
自定義一個主鍵:my_id=models.AutoField(primary_key=True)
若是你不指定主鍵的話,系統會自動添加一個主鍵字段到你的 model.
<5> BooleanField
A true/false field. admin 用 checkbox 來表示此類字段.
<6> TextField
一個容量很大的文本字段.
admin 用一個 <textarea> (文本區域)表示該字段數據.(一個多行編輯框).
<7> EmailField
一個帶有檢查Email合法性的 CharField,不接受 max_length 參數.
<8> DateField
一個日期字段. 共有下列額外的可選參數:
Argument 描述
auto_now 當對象被保存時,自動將該字段的值設置爲當前時間.一般用於表示 "last-modified" 時間戳.
auto_now_add 當對象首次被建立時,自動將該字段的值設置爲當前時間.一般用於表示對象建立時間.
(僅僅在admin中有意義...)
<9> DateTimeField
一個日期時間字段. 相似 DateField 支持一樣的附加選項.
<10> ImageField
相似 FileField, 不過要校驗上傳對象是不是一個合法圖片.#它有兩個可選參數:height_field和width_field,
若是提供這兩個參數,則圖片將按提供的高度和寬度規格保存.
<11> FileField
一個文件上傳字段.
要求一個必須有的參數: upload_to, 一個用於保存上載文件的本地文件系統路徑. 這個路徑必須包含 strftime #formatting,
該格式將被上載文件的 date/time
替換(so that uploaded files don't fill up the given directory).
admin 用一個<input type="file">部件表示該字段保存的數據(一個文件上傳部件) .
注意:在一個 model 中使用 FileField 或 ImageField 須要如下步驟:
(1)在你的 settings 文件中, 定義一個完整路徑給 MEDIA_ROOT 以便讓 Django在此處保存上傳文件.
(出於性能考慮,這些文件並不保存到數據庫.) 定義MEDIA_URL 做爲該目錄的公共 URL. 要確保該目錄對
WEB服務器用戶賬號是可寫的.
(2) 在你的 model 中添加 FileField 或 ImageField, 並確保定義了 upload_to 選項,以告訴 Django
使用 MEDIA_ROOT 的哪一個子目錄保存上傳文件.你的數據庫中要保存的只是文件的路徑(相對於 MEDIA_ROOT).
出於習慣你必定很想使用 Django 提供的 get_<#fieldname>_url 函數.舉例來講,若是你的 ImageField
叫做 mug_shot, 你就能夠在模板中以 {{ object.#get_mug_shot_url }} 這樣的方式獲得圖像的絕對路徑.
<12> URLField
用於保存 URL. 若 verify_exists 參數爲 True (默認), 給定的 URL 會預先檢查是否存在( 即URL是否被有效裝入且
沒有返回404響應).
admin 用一個 <input type="text"> 文本框表示該字段保存的數據(一個單行編輯框)
<13> NullBooleanField
相似 BooleanField, 不過容許 NULL 做爲其中一個選項. 推薦使用這個字段而不要用 BooleanField 加 null=True 選項
admin 用一個選擇框 <select> (三個可選擇的值: "Unknown", "Yes" 和 "No" ) 來表示這種字段數據.
<14> SlugField
"Slug" 是一個報紙術語. slug 是某個東西的小小標記(短籤), 只包含字母,數字,下劃線和連字符.#它們一般用於URLs
若你使用 Django 開發版本,你能夠指定 max_length. 若 max_length 未指定, Django 會使用默認長度: 50. #在
之前的 Django 版本,沒有任何辦法改變50 這個長度.
這暗示了 db_index=True.
它接受一個額外的參數: prepopulate_from, which is a list of fields from which to auto-#populate
the slug, via JavaScript,in the object's admin form: models.SlugField
(prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields.
<13> XMLField
一個校驗值是否爲合法XML的 TextField,必須提供參數: schema_path, 它是一個用來校驗文本的 RelaxNG schema #的文件系統路徑.
<14> FilePathField
可選項目爲某個特定目錄下的文件名. 支持三個特殊的參數, 其中第一個是必須提供的.
參數 描述
path 必需參數. 一個目錄的絕對文件系統路徑. FilePathField 據此獲得可選項目.
Example: "/home/images".
match 可選參數. 一個正則表達式, 做爲一個字符串, FilePathField 將使用它過濾文件名.
注意這個正則表達式只會應用到 base filename 而不是
路徑全名. Example: "foo.*\.txt^", 將匹配文件 foo23.txt 卻不匹配 bar.txt 或 foo23.gif.
recursive 可選參數.要麼 True 要麼 False. 默認值是 False. 是否包括 path 下面的所有子目錄.
這三個參數能夠同時使用.
match 僅應用於 base filename, 而不是路徑全名. 那麼,這個例子:
FilePathField(path="/home/images", match="foo.*", recursive=True)
...會匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif
<15> IPAddressField
一個字符串形式的 IP 地址, (i.e. "24.124.1.30").
<16> CommaSeparatedIntegerField
用於存放逗號分隔的整數值. 相似 CharField, 必需要有max_length參數.
'''
|
更多參數:linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
(
1
)null
若是爲
True
,Django 將用NULL 來在數據庫中存儲空值。 默認值是
False
.
(
1
)blank
若是爲
True
,該字段容許不填。默認爲
False
。
要注意,這與 null 不一樣。null純粹是數據庫範疇的,而 blank 是數據驗證範疇的。
若是一個字段的blank
=
True
,表單的驗證將容許該字段是空值。若是字段的blank
=
False
,該字段就是必填的。
(
2
)default
字段的默認值。能夠是一個值或者可調用對象。若是可調用 ,每有新對象被建立它都會被調用,若是你的字段沒有設置能夠爲空,那麼未來若是咱們後添加一個字段,<br>這個字段就要給一個default值
(
3
)primary_key
若是爲
True
,那麼這個字段就是模型的主鍵。若是你沒有指定任何一個字段的primary_key
=
True
,
Django 就會自動添加一個IntegerField字段作爲主鍵,因此除非你想覆蓋默認的主鍵行爲,
不然不必設置任何一個字段的primary_key
=
True
。
(
4
)unique
若是該值設置爲
True
, 這個數據字段的值在整張表中必須是惟一的
(
5
)choices
由二元組組成的一個可迭代對象(例如,列表或元組),用來給字段提供選擇項。 若是設置了choices ,默認的表單將是一個選擇框而不是標準的文本框,<br>並且這個選擇框的選項就是choices <br>中的選項。
|
3 settings配置git
若想將模型轉爲mysql數據庫中的表,須要在settings中配置:正則表達式
1
2
3
4
5
6
7
8
9
10
|
DATABASES
=
{
'default'
: {
'ENGINE'
:
'django.db.backends.mysql'
,
'NAME'
:
'bms'
,
# 要鏈接的數據庫,鏈接前須要建立好
'USER'
:
'root'
,
# 鏈接數據庫的用戶名
'PASSWORD'
:'',
# 鏈接數據庫的密碼
'HOST'
:
'127.0.0.1'
,
# 鏈接主機,默認本級
'PORT'
:
3306
# 端口 默認3306
}
}
|
注意1:NAME即數據庫的名字,在mysql鏈接前該數據庫必須已經建立,而上面的sqlite數據庫下的db.sqlite3則是項目自動建立 .USER和PASSWORD分別是數據庫的用戶名和密碼。設置完後,在啓動咱們的Django項目前,咱們須要激活咱們的mysql。而後,啓動項目,會報錯:no module named MySQLdb 。這是由於django默認你導入的驅動是MySQLdb,但是MySQLdb 對於py3有很大問題,因此咱們須要的驅動是PyMySQL ,因此咱們只須要找到項目名文件下的__init__,在裏面寫入:sql
1
2
|
import
pymysql
pymysql.install_as_MySQLdb()
|
最後經過兩條數據庫遷移命令便可在指定的數據庫中建立表 :數據庫
1
2
|
python manage.py makemigrations
#生成記錄,每次修改了models裏面的內容或者添加了新的app,新的app裏面寫了models裏面的內容,都要執行這兩條
python manage.py migrate
#執行上面這個語句的記錄來建立表,生成的表名字前面會自帶應用的名字,例如:你的book表在mysql裏面叫作app01_book表
|
建立新的應用, 都須要在setting中進行設置:
Django-admin.py startapp app01 # 應用名爲:app01
經過pycharm提供的功能來執行manage.py相關的指令:
給以前的字段添加一些數據,而後再添加一個字段,而後執行上面兩個指令,看看效果。
注意2:確保配置文件中的INSTALLED_APPS中寫入咱們建立的app名稱
1
2
3
4
5
6
7
8
9
|
INSTALLED_APPS
=
[
'django.contrib.admin'
,
#這是django給你提供的一些特殊功能的配置(應用,只是我們看不到),也在應用這裏給配置的,這些功能若是你註銷了,那麼咱們執行同步數據庫指令以後,<br>就不會生成那些django自帶的表了。由於執行數據庫同步語句的時候,django會找這裏面全部的應用,找到他們的models來建立表
'django.contrib.auth'
,
'django.contrib.contenttypes'
,
'django.contrib.sessions'
,
'django.contrib.messages'
,
'django.contrib.staticfiles'
,
"book"
#直接寫app的名字也行,寫'app01.apps.App01Config'也行
]
|
注意3:若是報錯以下:
1
|
django.core.exceptions.ImproperlyConfigured: mysqlclient
1.3
.
3
or
newer
is
required; you have
0.7
.
11.None
|
MySQLclient目前只支持到python3.4,所以若是使用的更高版本的python,須要修改以下:
經過查找路徑C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql
這個路徑裏的文件吧
1
2
|
if
version < (
1
,
3
,
3
):
raise
ImproperlyConfigured(
"mysqlclient 1.3.3 or newer is required; you have %s"
%
Database.__version__)
|
註釋掉 就OK了。
注意4: 若是想打印orm轉換過程當中的sql,須要在settings中進行以下配置:(學了增長記錄的語句在過來配置吧)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
LOGGING
=
{
'version'
:
1
,
'disable_existing_loggers'
:
False
,
'handlers'
: {
'console'
:{
'level'
:
'DEBUG'
,
'class'
:
'logging.StreamHandler'
,
},
},
'loggers'
: {
'django.db.backends'
: {
'handlers'
: [
'console'
],
'propagate'
:
True
,
'level'
:
'DEBUG'
,
},
}
}
|
還有一種查看sql語句的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from
app01
import
models
def
add_book(request):
'''
添加表記錄
:param request: http請求信息
:return:
'''
book_obj
=
models.Book(title
=
'python'
,price
=
123
,pub_date
=
'2012-12-12'
,publish
=
'人民出版社'
)
book_obj.save()
from
django.db
import
connection
#經過這種方式也能查看執行的sql語句
print
(connection.queries)
return
HttpResponse(
'ok'
)
|
表建立完了,咱們就來個增刪改查,來個圖書管理系統。
在python中orm的對應關係有三種:
類 ---------->表
類對象 ---------->行(記錄)
類屬性 ---------->表的字段
首先想操做表的增刪改查,你須要導入這個表
1
2
3
4
5
6
7
8
9
10
|
#在邏輯代碼中導入你要操做的表
from
app01
import
models
def
add_book(request):
'''
添加表記錄
:param request: http請求信息
:return:
'''
models.Book(title
=
'python'
,price
=
123
,pub_date
=
'2012-12-12'
,publish
=
'人民出版社'
)
|
方式1
1
2
|
book_obj
=
Book(title
=
"python葵花寶典"
,state
=
True
,price
=
100
,publish
=
"蘋果出版社"
,pub_date
=
"2012-12-12"
)
#實例化一個對象表示一行記錄,時間日期若是隻寫日期的話,<br>時間默認是00.00.00,注意日期寫法必須是2012-12-12這種格式
book_obj.save()
#就是pymysql的那個commit提交
|
方式2(用的多)
1
2
3
4
5
6
|
# create方法的返回值book_obj就是插入book表中的python葵花寶典這本書籍紀錄對象
book_obj
=
Book.objects.create(title
=
"python葵花寶典"
,state
=
True
,price
=
100
,publish
=
"蘋果出版社"
,pub_date
=
"2012-12-12"
)
#這個返回值就像是mysql裏面我們講的那個<br>new對象,還記得嗎,他跟上面那種建立方式建立的那個對象是同樣的
#這個Book.objects就像是一個Book表的管理器同樣,提供了增刪改查全部的方法
print
(book_obj.title)
#能夠基於這個對象來取這個新添加的記錄對象的屬性值
dic1
=
{
'title'
:
'linux'
,
'state'
=
True
,
'price'
:
100
,
'publish'
=
'2018-12-12'
}
#這樣寫的時候,注意若是你用post提交過來的請求,有個csrf_token的鍵值對要刪除,而且<br>request.POST是不能直接在request.POST裏面進行修改和刪除的,data = request.POST.dict()轉換成普通的字典-->Book.objects.create(**data)
book.objects.create(
*
*
dic1)
|
3、查詢表紀錄
還記得表類.objects像是一個管理器,提供了增刪改查的方法,Book.objects.all()獲取全部的書籍,查詢這裏你們就掌握誰調用的下面的方法
1
2
3
|
<
1
>
all
(): 查詢全部結果,結果是queryset類型
<
2
>
filter
(
*
*
kwargs): 它包含了與所給篩選條件相匹配的對象,結果也是queryset類型 Book.objects.
filter
(title
=
'linux'
,price
=
100
)
|
1
|
#裏面的多個條件用逗號分開,而且這幾個條件必須都成立,是and的關係,or關係的咱們後面再學,直接在這裏寫是搞不定or的
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<
3
> get(
*
*
kwargs): 返回與所給篩選條件相匹配的對象,不是queryset類型,是行記錄對象,返回結果有且只有一個,
若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。捕獲異常
try
。 Book.objects.get(
id
=
1
)
<
4
> exclude(
*
*
kwargs): 排除的意思,它包含了與所給篩選條件不匹配的對象,沒有不等於的操做昂,用這個exclude,返回值是queryset類型
<
5
> order_by(
*
field): 對查詢結果排序
<
6
> reverse(): 對查詢結果反向排序
<
8
> count(): 返回數據庫中匹配查詢(QuerySet)的對象數量。
<
9
> first(): 返回第一條記錄 Book.objects.
all
()[
0
]
=
Book.objects.
all
().first(),獲得的都是model對象,不是queryset
<
10
> last(): 返回最後一條記錄
<
11
> exists(): 若是QuerySet包含數據,就返回
True
,不然返回
False
<
12
> values(
*
field): 返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列
model的實例化對象,而是一個可迭代的字典序列
<
13
> values_list(
*
field): 它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列
<
14
> distinct(): 從返回結果中剔除重複紀錄
|
打印一個對象,讓他顯示一個可以看懂的值,__str__,models.py的數據表類裏面定義一個__str__方法就能夠了
1
2
3
4
5
6
7
8
9
10
11
12
|
#__str__方法的使用
class
MyClass:
def
__init__(
self
,name,age):
self
.name
=
name
self
.age
=
age
def
__str__(
self
):
return
self
.name
+
'>>>'
+
str
(
self
.age)
a
=
MyClass(
'chao'
,
18
)
b
=
MyClass(
'wc'
,
20
)
print
(a)
print
(b)
|
models.py的__str__的寫法:
1
2
3
4
5
6
7
8
9
10
11
12
|
from
django.db
import
models
# Create your models here.
class
Book(models.Model):
id
=
models.AutoField(primary_key
=
True
)
title
=
models.CharField(max_length
=
32
)
price
=
models.DecimalField(max_digits
=
8
,decimal_places
=
2
,)
pub_date
=
models.DateTimeField()
#必須存這種格式"2012-12-12"
publish
=
models.CharField(max_length
=
32
)
def
__str__(
self
):
#後添加這個str方法,也不須要從新執行同步數據庫的指令
return
self
.title
#當咱們打印這個類的對象的時候,顯示title值
|
基於雙下劃線的模糊查詢
1
2
3
4
5
6
7
8
|
Book.objects.
filter
(price__in
=
[
100
,
200
,
300
])
Book.objects.
filter
(price__gt
=
100
)
Book.objects.
filter
(price__lt
=
100
)
Book.objects.
filter
(price__range
=
[
100
,
200
])
Book.objects.
filter
(title__contains
=
"python"
)
Book.objects.
filter
(title__icontains
=
"python"
)
Book.objects.
filter
(title__startswith
=
"py"
)
Book.objects.
filter
(pub_date__year
=
2012
)
|
4、刪除表紀錄
刪除方法就是 delete()。它運行時當即刪除對象而不返回任何值。例如:
1
|
model_obj.delete()
|
你也能夠一次性刪除多個對象。每一個 QuerySet 都有一個 delete() 方法,它一次性刪除 QuerySet 中全部的對象。
例如,下面的代碼將刪除 pub_date 是2005年的 Entry 對象:
1
|
Entry.objects.
filter
(pub_date__year
=
2005
).delete()
|
在 Django 刪除對象時,會模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。例如:
1
2
3
|
b
=
Blog.objects.get(pk
=
1
)
# This will delete the Blog and all of its Entry objects.
b.delete()
|
要注意的是: delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 自己。這是一種保護機制,是爲了不意外地調用 Entry.objects.delete() 方法致使 全部的 記錄被誤刪除。若是你確認要刪除全部的對象,那麼你必須顯式地調用:
1
|
Entry.objects.
all
().delete()
|
若是不想級聯刪除,能夠設置爲:
1
|
pubHouse
=
models.ForeignKey(to
=
'Publisher'
, on_delete
=
models.SET_NULL, blank
=
True
, null
=
True
)
|
5、修改表紀錄
1
|
Book.objects.
filter
(title__startswith
=
"py"
).update(price
=
120
),
|
此外,update()方法對於任何結果集(QuerySet)均有效,這意味着你能夠同時更新多條記錄update()方法會返回一個整型數值,表示受影響的記錄條數。
注意:<input type="date" class="form-control" id="book_pub_date" placeholder="出版日期" name="book_pub_date" value="{{ edit_obj.pub_date|date:'Y-m-d' }}">,type='date'的input標籤,value的值必須是'Y-m-d'的格式,這個標籤才能認識並被賦值,因此,要經過date過濾給它改變格式。
實現功能:book單表的增刪改查
# 建立表 from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=32, unique=True) price = models.DecimalField(max_digits=16, decimal_places=2) pub_time = models.DateField() publish = models.CharField(max_length=20)
# urls.py """ormproject URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^book/', views.books, name='books'), url(r'^add_book/', views.add_book, name='add_book'), url(r'^edit_book/(\d+)/', views.edit_book, name='edit_book'), url(r'^delet_book/(\d+)/', views.delet_book, name='delet_book'), ]
# views.py from django.shortcuts import render,HttpResponse, redirect from django.urls import reverse from app01 import models # Create your views here. def books(request): ''' 展現全部書籍信息 :param request: :return: ''' all_books = models.Book.objects.all() print(all_books) return render(request, 'index.html', {'all_books': all_books}) def add_book(request): # # 插入數據方式1 # book_obj = models.Book(title='西遊記', price=12, pub_time='1999-9-9', publish='2號出版社') # book_obj.save() # return HttpResponse('數據插入成功') # 插入數據方式2 # models.Book.objects.create(title='三國演義', price=13, pub_time='1888-3-3', publish='1號出版社') # return HttpResponse('數據插入成功') if request.method == "GET": return render(request, 'add_book.html') else: title = request.POST.get('title') price = request.POST.get('price') pub_time = request.POST.get('pub_time') publish = request.POST.get('publish') models.Book.objects.create(title=title, price=price, pub_time=pub_time, publish=publish) return redirect(reverse('books')) def edit_book(request,n): # print(n) publish = models.Book.objects.filter(id=n)[0].publish pub_time = models.Book.objects.filter(id=n)[0].pub_time title = models.Book.objects.filter(id=n)[0].title price = models.Book.objects.filter(id=n)[0].price if request.method == 'GET': return render(request, 'edit_book.html',{'n':n,'title':title, 'price':price, 'pub_time':pub_time, 'publish':publish}) else: title = request.POST.get('title') price = request.POST.get('price') pub_time = request.POST.get('pub_time') publish = request.POST.get('publish') models.Book.objects.filter(id=n).update(title=title, price=price, pub_time=pub_time, publish=publish) return redirect(reverse('books')) def delet_book(request, n): print(n) models.Book.objects.filter(id=n).delete() return redirect(reverse('books'))
# 主頁 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> {# <link rel="stylesheet" href="http://code.jquery.com/jquery-1.4.1.min.js">#} <style> tbody td { height: 40px!important; line-height: 40px!important; } </style> </head> <body> <div class="container"> <div style="margin-top: 100px;"></div> <div class="row"> <div class="col-md-6 col-md-offset-3" > <a id="a1" class="btn btn-success" href="{% url 'add_book' %}" >添加圖書</a> <table class="table table-bordered" > <thead> <tr> <th>id</th> <th>書名</th> <th>價錢</th> <th>出版時間</th> <th>出版社</th> <th>操做</th> </tr> </thead> <tbody> {% for foo in all_books %} <tr> <td>{{ foo.id }}</td> <td>{{ foo.title }}</td> <td>{{ foo.price }}</td> <td>{{ foo.pub_time|date:'Y-m-d' }}</td> <td>{{ foo.publish }}</td> <td> <a class="btn btn-success" href="{% url 'edit_book' foo.id %}">編輯</a> <a class="btn btn-danger" href="{% url 'delet_book' foo.id %}">刪除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
# 添加頁面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class="container"> <div style="margin-top: 100px;"></div> <div class="row1"> <div class="col-md-6 col-md-offset-3"> <form class="form-horizontal" name="{% url 'add_book' %}" method="post"> {% csrf_token %} <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">書名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="title" placeholder="書名" name="title"> </div> </div> <div class="form-group"> <label for="text" class="col-sm-2 control-label">價格</label> <div class="col-sm-10"> <input type="text" class="form-control" id="price" placeholder="價格" name="price"> </div> </div> <div class="form-group"> <label for="text" class="col-sm-2 control-label">出版時間</label> <div class="col-sm-10"> <input type="text" class="form-control" id="pub_time" placeholder="出版時間" name="pub_time"> </div> </div> <div class="form-group"> <label for="text" class="col-sm-2 control-label">出版社</label> <div class="col-sm-10"> <input type="text" class="form-control" id="publish" placeholder="出版社" name="publish"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">保存</button> </div> </div> </form> </div> </div> </div> </body> </html>
# 修改頁面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class="container"> <div style="margin-top: 100px;"></div> <div class="row1"> <div class="col-md-6 col-md-offset-3"> <form class="form-horizontal" name="{% url 'edit_book' n %}" method="post"> {% csrf_token %} <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">書名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="title" placeholder="書名" name="title" value="{{ title }}"> </div> </div> <div class="form-group"> <label for="text" class="col-sm-2 control-label">價格</label> <div class="col-sm-10"> <input type="text" class="form-control" id="price" placeholder="價格" name="price" value="{{ price }}"> </div> </div> <div class="form-group"> <label for="text" class="col-sm-2 control-label">出版時間</label> <div class="col-sm-10"> <input type="text" class="form-control" id="pub_time" placeholder="出版時間" name="pub_time" value="{{ pub_time|date:'Y-m-d' }}"> </div> </div> <div class="form-group"> <label for="text" class="col-sm-2 control-label">出版社</label> <div class="col-sm-10"> <input type="text" class="form-control" id="publish" placeholder="出版社" name="publish" value="{{ publish }}"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">保存</button> </div> </div> </form> </div> </div> </div> </body> </html>