我我的對django中ORM的實現的理解:在models中寫好類,經過migrate寫入數據庫。接着使用django封裝好的方法,進行傳參、調用。javascript
1、數據庫配置css
(一).在settings.py中配置DATABASEShtml
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 數據庫引擎 'NAME': 'mydb', # 數據庫名稱 'USER': 'root', # 鏈接數據庫的用戶名 'PASSWORD': 'qwe123', # 鏈接數據庫的密碼 'HOST': '127.0.0.1', # mysql服務器的域名和ip地址 # 'USER': 'admin', # 'PASSWORD': 'Root110qwe', # 'HOST': '192.168.72.130', 'PORT': '3308', # mysql的一個端口號,默認是3306 } }
注意事項:前端
(1).只要"HOST"不爲127.0.0.1的時候,對於MySQL的root來講,都是屬於遠程鏈接(填寫虛擬機中Linux的IP也算遠程了)java
而root用戶只能在本地使用,它是拒絕遠程鏈接的。因此,不填寫127.0.0.1的話,能夠考慮使用與root同權限的用戶進行鏈接。python
(2).NAME中所指定的數據庫,必定要事先建好!數據庫都沒有,你讓django怎麼去連?連哪一個?Ps:這是MySQL,不是MongoDBmysql
(二).安裝數據庫鏈接器c++
在你本身使用的那個環境中,pip install pymsqlsql
(三).數據庫
import pymysql pymysql.install_as_MySQLdb()
2、使用django中的模型
(一).進入你的app,打開"models.py"
最簡單的示例1:
# blog/models.py from django.db import models # Create your models here. class User(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=30) age = models.IntegerField() def __str__(self): return 'User<id=%s,name=%s,age=%s>'%( self.id,self.name,self.age)
注意事項:
(1).模型必須都寫在app的models.py中。
(2).模型所屬的app必須被註冊到"settings.py"的"INSTALL_APPS"中去,否則下面(二)的時候,是映射不到數據庫中去的。
(3).全部的類,都必須繼承"models.Model"才能生成映射後的表格。
(4).一個數據表對應模型中的類名。表中的字段,對應模型中的類屬性。
(5).字段是varchar類型的話(它對應的是CharField),必須在CharField中設置max_length的值,否則會報錯。
(6).AutoField()能夠不寫,django也會爲咱們自動建立。
(二).將模型映射到數據庫中
(1).首先要建立一個映射文件
進入"manage.py"這個文件所在的目錄,敲命令:python manage.py makemigrations
(2).將映射文件中的映射數據真正提交到數據庫中
敲命令:python manage.py migrate
(3).兩個命令長相差很少,一開始傻傻分不清,咋記?
migration是名詞,因此只是個映射文件。migrate是動詞,[/動起來~],纔會真正起做用了。
(三).添加新字段的方式
有新字段要增長了?不用去MySQL中敲那麼長一大段代碼了,直接在django中進行操做就行。[/竊竊私語]:MySQL原生態添加新字段的代碼真心很長 — —!
(1).直接點開models.py,把你想要加的字段,寫進對應的類中
注意:新的字段須要指定"null=True"或者也能夠用"default='xxx'"來代替。這兩個你要是一個都不寫,migration就會報錯!由於原來的字段已經存在於數據表中了,數據表中可能已有數據了。那你這個新字段的值是什麼?什麼都沒有,那不就報錯了。
(2).cd到"manage.py"這個文件所在的目錄中。
(3).再次執行命令:
python manage.py makemigrations # 等它執行完 # 新增字段會讓你確認。直接輸入 y 回車 # 再執行 python manage.py migrate
(四).修改字段
發現字段寫錯了?參考(三)同理可得
再次執行migrations和migrate
3、數據的增刪改查
(一).增(add)
# blog/views.py from .models import User def add_user(request): # 方法一: # tiazi = User(name='tiazi',age=18) # tiazi.save() # 方法二: # xm = User() # xm.name = 'xiaoming' # xm.age = 19 # xm.save() # 方法三: # User.objects.create(name='xiaohong',age=20,) # 方法四: User.objects.get_or_create(name='xiaohua',age=21) return HttpResponse('插入數據成功!!!')
(1).字段編碼有問題該如何處理
當帶有漢字的數據記錄插入表時報錯了,基本是屬於表的編碼沒有設置好,執行下面的代碼
alter table 數據表名 CONVERT TO CHARACTER SET utf8;
(二).刪(delete)
在MySQL中,我已寫了老師曾說過一段話:「在開發中,有個不成文的規矩:寧肯讓數據做廢,也不要去刪」
我我的比較承認,萬一你刪錯了呢?哪怕是測試用的數據,刪錯了,不是給本身找麻煩!
# blog/views.py def delete_user(request): User.objects.get(id=1).delete() return HttpResponse('刪除數據成功!!!')
(三).改(update)
# blog/views.py def update_user(request): # rs = User.objects.get(name='xiaoming') # rs.name = 'Xiaoming' # rs.save() # User.objects.filter(name='Xiaoming').update(name='XM') User.objects.all().update(city='zhangsan') return HttpResponse('更新數據成功!!!')
(四).查(selcet)
# blog/views.py def search_user(request): # 查詢全部記錄對象 # rs = User.objects.all() # 查詢一個記錄對象 # rs = User.objects.get(id=1) # 獲取知足條件的對象 rs = User.objects.filter(name='xiaoming') print(rs) return HttpResponse('查詢數據成功!!!')
(1).經常使用的查詢
獲取全部記錄: rs = User.objects.all() 獲取第一條數據: rs = User.objects.first() 獲取最後一條數據: rs = User.objects.last() 根據參數提供的條件獲取過濾後的記錄: rs = User.objects.filter(name='xiaoming') 注意:filter(**kwargs)方法:根據參數提供的提取條件,獲取一個過濾後的QuerySet。 排除name等於xiaoming的記錄: rs = User.objects.exclude(name='xiaoming') 獲取一個記錄對象: rs = User.objects.get(name='xiaoming') 注意:get返回的對象具備惟一性質,若是符合條件的對象有多個,則get報錯! 對結果排序order_by: rs = User.objects.order_by('age') 多項排序: rs = User.objects.order_by('age','id') 逆向排序: rs = User.objects.order_by('-age') 將返回來的QuerySet中的Model轉換爲字典 rs = User.objects.all().values() 獲取當前查詢到的數據的總數: rs = User.objects.count()
(2).經常使用的查詢對象的條件參數
查找對象的條件的意思是傳給以上方法的一些參數。至關因而SQL語句中的where語句後面的條件,語法爲"字段名__規則",如下將對這些規則進行說明: exact 至關於等於號: rs = User.objects.filter(name__exact='xiaoming') iexact:跟exact,只是忽略大小寫的匹配。 contains 包含: rs = User.objects.filter(name__contains='xiao') icontains 跟contains,惟一不一樣是忽略大小寫。 startwith 以什麼開始: rs = User.objects.filter(name__startswith='xiao') istartswith:同startswith,忽略大小寫。 endswith:同startswith,以什麼結尾。 iendswith:同istartswith,以什麼結尾,忽略大小寫。 in 成員所屬: rs = User.objects.filter(age__in=[18,19,20]) gt 大於: rs = User.objects.filter(age__gt=20) gte 大於等於: rs = User.objects.filter(age__gte=20) lt 小於: rs = User.objects.filter(age__lt=20) lte 小於等於: rs = User.objects.filter(age__lte=20) range 區間: rs = User.objects.filter(age__range=(18,20)) isnull 判斷是否爲空: rs = User.objects.filter(country__isnull=True) 切片: rs = User.objects.all()[:2] 注意:不能使用負數做爲切片。
(五).注意事項
(1).filter()返回一個查詢集合(能夠視做列表)
(2).get()只返回一個對象,沒有對象返回會報錯(類名.DoesNotExist)
4、經常使用的模型字段類型
(一).IntegerField
整型,映射到數據庫中的int類型。
(二).CharField
字符類型,映射到數據庫中的varchar類型。必須制定max_length的值,否則就報錯。
(三).TextField
文本類型,映射到數據庫中的text類型。
(四).BooleanField
布爾類型,映射到數據庫中的tinyint類型,在使用的時候,傳遞True/False進去。若是要能夠爲空,則用NullBooleanField。
(五).DateField
日期類型,沒有時間。映射到數據庫中是date類型,
在使用的時候,能夠設置DateField(auto_now=True)每次修改對象時,自動設置該字段爲當前時間。
設置DateField(auto_now_add=True)當對象第一次被建立時自動設置當前時間。
注意:DateField(auto_now=True)只有調用Model.save()方法纔會調用,QuerySet.update方法將不會調用。這個參數只是Date和DateTime以及Time類纔有的。
(六).DateTimeField
日期+時間類型。映射到數據庫中的是datetime類型,在使用的時候,傳遞datetime.datetime()進去。
一樣能夠設置auto_now_add和auto_now
(七).補充
(1).關於django時區的問題
此博主總結得挺好:https://www.cnblogs.com/alan-babyblog/p/5739004.html
若是要使用本地時間,設置這兩個屬性:TIME_ZONE="Asia/Shanghai"; USE_TZ=False
(2).修改MySQL的時區
用root用戶進入MySQL中,直接敲命令:set time_zone='+8:00';
而後重啓MySQL服務:sudo service mysqld restart
再次進入MySQL中,查看時間的命令:select now();
5、表關係的實現
(一).一對多表關係
在MySQL中一對可能是經過外鍵實現的,在django模型中經過ForeignKeyField類型實現。
(二).一對一表關係
在Mysql中一對一是經過外鍵+惟一鍵實現的,在django模型中經過OneToOneField類型實現。
(三).多對多表關係
在MySQL中多對可能是經過中間表外鍵+聯合惟一鍵實現的,在django模型中經過ManyToManyField類型實現。中間表模型會自動幫咱們建立好。
(四).示例
(1).在app中的models.py中寫好類
class Department(models.Model): d_id = models.AutoField(primary_key=True) d_name = models.CharField(max_length=30) def __str__(self): return 'Department<d_id=%s,d_name=%s>'%( self.d_id,self.d_name ) class Student(models.Model): s_id = models.AutoField(primary_key=True) s_name = models.CharField(max_length=30) department = models.ForeignKey('Department') course = models.ManyToManyField('Course') def __str__(self): return 'Student<s_id=%s,s_name=%s>'%( self.s_id,self.s_name ) class Course(models.Model): c_id = models.AutoField(primary_key=True) c_name = models.CharField(max_length=30) def __str__(self): return 'Course<c_id=%s,c_name=%s>'%( self.c_id,self.c_name ) class Stu_detail(models.Model): s_id = models.OneToOneField('Student') age = models.IntegerField() gender = models.BooleanField(default=1) country = models.CharField(max_length=30,null=True) def __str__(self): return 'Stu_detail<s_id=%s,age=%s,gender=%s,country=%s>'%( self.s_id,self.age,self.gender,self.country )
(2).分別執行
python manage.py makemigrations App_name
python manage.py migrate App_name
(3).在視圖中對關係表的操做
from .models import Department,Student,Course def add_info(request): # d1 = Department(d_name='AA') # d1.save() # 一對多關係加內容 # s1 = Student(s_name='xiaoming') # s1.department = d1 # s1.save() # 多對多關係添加內容 # c1 = Course(c_name='python') # s1 = Student.objects.first() # c1.save() # s1.course.add(c1) return HttpResponse('添加數據成功') def search_info(request): rs = Student.objects.all()[0] # 一對多的查詢 print(rs.department) # 多對多的正向查詢 print(rs.course.all()) cs = Course.objects.first() # 多對多反向查詢 print(cs.student_set.all()) return HttpResponse('查詢數據成功')
(4).前向查詢
若是一個模型有ForeignKey(),那麼該模型的實例能夠經過屬性訪問的方式,去訪問關聯的(外部)對象。
s1 = Student.objects.get(s_id=1) print(s1) # <Student: Student<s_id=1,s_name=xiaoming>> print(s1.department) # <Department: Department<d_id=6,d_name=AA>> # 還能夠經過外鍵屬性獲取和設置 dx = Department.objects.get(d_id=3) print(dx) # <Department: Department<d_id=3,d_name=設計>> s1.department = dx print(s1.department ) # <Department: Department<d_id=3,d_name=設計>> s1.save() # 必定要save()了纔會保存到數據庫
(5).反向查詢,方式1
d1 = Department.objects.get(d_id=1) print(d1) # <Department: Department<d_id=1,d_name=軟件>> print(d1.student_set.all()) """ <QuerySet [<Student: Student<s_id=2,s_name=xiaohong>>, <Student: Student<s_id=3,s_name=xiaohua>>, <Student: Student<s_id=4,s_name=xiaoxin>>, <Student: Student<s_id=5,s_name=小明>>]> """
from blog.models import Student,Department,Course d1 = Department.objects.get(d_id=1) print(d1.student.all()) """ <QuerySet [<Student: Student<s_id=2,s_name=xiaohong>>, <Student: Student<s_id=3,s_name=xiaohua>>, <Student: Student<s_id=4,s_name=xiaoxin>>, <Student: Student<s_id=5,s_name=小明>>]> """
6、處理關聯對象的其它方法
(一).add(obj1, obj2, ...)
添加一指定的模型對象到關聯的對象集中。(一對多,多對多)。使用這個add的前提是要數據庫中已經有的數據。
d1 = Department.objects.get(d_id=4) print(d1) # <Department: Department<d_id=4,d_name=GG>> st = Student.objects.get(s_id=6) print(st) #<Student: Student<s_id=6,s_name=xx>> d1.student.add(st) c1 = Course.objects.get(c_id=2) st.course.add(c1)
(二).create(**kwargs)
建立一個新的對象,將它保存並放在關聯的對象集中,返回新建立的對象。(一對多,多對多)。添加不存在的數據,將數據直接存入數據庫。
# 繼續使用上面的代碼 print(st) #<Student: Student<s_id=6,s_name=xx>> print(st.course.create(c_name='c++')) #<Course: Course<c_id=3,c_name=c++>> print(st.course.all()) # <QuerySet [<Course: Course<c_id=3,c_name=c++>>]>
(三).remove(obj1, obj2, ...)
從關聯的對象集中刪除指定的模型對象。(多對多)。刪除的是關係表中的數據。
print(s3) # <Student: Student<s_id=3,s_name=xiaohua>> print(c1) # <Course: Course<c_id=2,c_name=java>> print(s3.course.all()) """ <QuerySet [<Course: Course<c_id=1,c_name=python>>, <Course: Course<c_id=2,c_name=java>>, <Course: Course<c_id=3,c_name=c++>>]> """ s3.course.remove(c1)
(四).clear()
從關聯的對象集中刪除全部的對象。(多對多)
s3.course.clear()
(五).直接賦值
print(s2) # <Student: Student<s_id=2,s_name=xiaohong>> print(cs) # <QuerySet [<Course: Course<c_id=3,c_name=c++>>]> print(s2.course.all()) # <QuerySet []> s2.course = cs print(s2.course.all()) # <QuerySet [<Course: Course<c_id=3,c_name=c++>>]>
(六).注意事項
(1).add()、create()、remove()和clear()都會立刻更新數據庫。換句話說,在關聯的任何一端,都不須要再調用save()方法。
7、多表查詢
(一).跨關聯關係的查詢
(1).例:
# 查詢學院名字爲‘軟件的’的學生的信息 Student.objects.filter(department__d_name='軟件')
(二).反向工做
若要引用一個「反向」的關係,只須要使用該模型的小寫的名稱。
(1).例:
# 查詢學生名字中包含‘xiao’的學生的學院信息 Department.objects.filter(student__s_name__contains='xiao')
(三).
(1).例:
# 查詢學號爲1的學生全部的課程 Course.objects.filter(student__s_id=1) # 查詢報了課程1的全部的學生 Student.objects.filter(course__c_id=1) # 查詢報了'python'課程的的學生的所屬學院的信息 Department.objects.filter(student__course__c_name='python')
建立博客的小案例
這個小案例只是單表的增刪改查。事先先建好一個名爲myblog的應用。
(一).先把模板作出來
有了實際的頁面,能夠根據頁面來知道要實現些什麼功能。
Ps:代碼都是測試經過後放上來的,功能也都實現了,因此頁面上的變量都不刪了。
(1).建立父模板
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> <link rel="stylesheet" href="{% static "css/myblog.css" %}"> </head> <body> <div class="nav"> <ul> <li> <a href="{% url "myblog_index" %}" class="goto_homepage" style="margin-left: 200px;">首頁</a> </li> </ul> </div> <br><br><br> <div> {% block bodyblock %} {% endblock %} </div> </body> </html>
(2).index頁面,主頁
{% extends 'myblog/demo_base.html' %} {% block title %} 首頁 {% endblock %} {% block bodyblock %} <table width="150"> <tr> <td><a href="{% url "write_blog" %}" class="homepage_function_button">添加文章</a></td> <td><a href="{% url "blog_list" %}" class="homepage_function_button">文章列表</a></td> </tr> </table> {% endblock %}
(3).add頁面,添加一篇博客
{% extends 'myblog/demo_base.html' %} {% block title %} 添加博客 {% endblock %} {% block bodyblock %} {% block h1_title %} <h1>添加新文章</h1> {% endblock %} <br> <form action="" method="POST"> {% csrf_token %} 標題:<input type="text" autocomplete="off" id="title" placeholder="請輸入標題" name="title" value="{% block blog_title %}{% endblock %}"> <br><br> 內容:<textarea name="content" id="content" placeholder="請輸入內容" cols="30" rows="10">{% block blog_content %}{% endblock %}</textarea> <br><br> <button type="submit">發佈博客</button> </form> {% endblock %}
(4).update頁面,修改一篇博客
修改頁面與添加頁面很像,因此直接繼承add.html
{% extends "myblog/demo_add.html" %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}修改博客{% endblock %}</title> </head> <body> {% block h1_title %} <h1>修改文章</h1> {% endblock %} {% block blog_title %}{{ rs.blog_tilt }}{% endblock %} {% block blog_content %}{{ rs.blog_content }}{% endblock %} </body> </html>
(5).detail頁面,顯示一篇博客的詳情
{% extends 'myblog/demo_base.html' %} {% block title %} 文章詳情 {% endblock %} {% block bodyblock %} <h1>文章詳情</h1> <br> 標題:{{ rs.blog_tilt }} <br> 博客內容:{{ rs.blog_content }} {% endblock %}
(6).list頁面,列出全部的博客
不只有全部博客的列表,還擁有功能鍵。
{% extends 'myblog/demo_base.html' %} {% block title %} 文章列表 {% endblock %} {% block bodyblock %} <h1 style="margin-left: 100px">文章列表</h1> <br> <table width="500px"> <thead style="font-size:20px"> <tr> <th>標題</th> <th>操做</th> </tr> </thead> <tbody> {% for each in rs %} <tr class="lightstick"> <th><a href="{% url "blog_detail" each.id %}">{{ each.blog_tilt }}</a><br></th> <th><a href="{% url "update_blog" each.id %}">編輯</a> | <a href="javascript:void(0);" onclick="delete_confirm('{% url "delete_blog" each.id %}');">刪除</a> </th> </tr> {% endfor %} </tbody> {# 看着下面的表格的格式寫循環 #} {# <tbody>#} {# <tr>#} {# <th><a href="">文章1</a></th>#} {# <th><a href="">編輯</a> | <a href="">刪除 </a></th>#} {# </tr>#} {# <tr>#} {# <th><a href="">文章2</a></th>#} {# <th><a href="">編輯</a> | <a href="">刪除 </a></th>#} {# </tr>#} {# </tbody>#} </table> <script> function delete_confirm(url) { if (confirm("肯定要刪除嗎?")) { window.location = url; } } </script> {% endblock %}
(二).寫CSS(可選步驟)
只是爲了稍微好看一點點,此步驟可省略。
/*此CSS文件是myblog的樣式*/ * { margin: 0; padding: 0; } /*導航欄 START*/ .nav { width: 100%; height: 50px; position: absolute; background: ghostwhite; border: none; border-bottom: lightblue 1px solid; } .nav ul li { list-style: none; } /*導航欄 END*/ /*導航欄 首頁 連接,用於返回首頁 START*/ .goto_homepage { display: block; width: 50px; height: 50px; line-height: 50px; text-decoration: none; text-align: center; transition: all 300ms; } .goto_homepage:hover { text-decoration: none; background: rgb(180, 9, 28); color: white; box-shadow: 4px 4px 5px lightgrey; transition: all 300ms; } /*導航欄 首頁 連接,用於返回首頁 END*/ /*首頁 添加文章、文章列表 按鈕樣式 START*/ .homepage_function_button { display: block; width: 80px; height: 30px; line-height: 30px; text-align: center; font-family: "微軟雅黑"; font-size: 16px; transition: all 300ms; } .homepage_function_button:hover { text-decoration: none; background: rgb(180, 9, 28); color: white; box-shadow: 2px 2px 5px lightgrey; } /*首頁 添加文章、文章列表 按鈕樣式 END*/ /*博客列表的光棒效果*/ .lightstick:hover { background: rgba(211, 211, 211, 0.25); } /* 通用的a標籤的僞類 START */ a { text-decoration: none; transition: color 200ms; color: black; } a :link { color: black; } a:visited { color: black; } a:hover { text-decoration: underline; color: rgb(180, 9, 28); } a:active { color: black; } /* 通用的a標籤的僞類 END */
(三).設計模型
# myblog/models.py from django.db import models # Create your models here. class SimpleBlog(models.Model): blog_tilt = models.CharField(max_length=100) blog_content = models.TextField() create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True)
注意:別忘了去Linux上makemigrations和mirgate
(四).編寫視圖函數
from django.shortcuts import render, HttpResponse, redirect, reverse from .models import * # Create your views here. # --------------- app:myblog 的邏輯 START --------------- def index(request): """ myblog的首頁 : "myblog/demo_index.html" :param request: :return: 顯示首頁 -> myblog/demo_index.html """ return render( request, "myblog/demo_index.html", ) def write_blog(request): """ 寫博客的頁面 : "myblog/demo_add.html" :param request: :return: 顯示寫博客的頁面 -> myblog/demo_add.html """ if request.method == "GET": return render(request, "myblog/demo_add.html") elif request.method == "POST": # 獲取到前端form中的內容 tile = request.POST.get("title") content = request.POST.get("content") # 放入數據庫 try: SimpleBlog.objects.create(blog_tilt=tile, blog_content=content) return HttpResponse("提交成功") except Exception as e: return HttpResponse("建立博客時,發生錯誤:{}".format(e)) else: return HttpResponse("無效的請求!") def get_all_blog_list(request): """ 列出全部的博客 : "myblog/demo_list.html" 左側是博客標題。 右邊是編輯、刪除等功能鍵。 :param request: :return: 顯示全部博客到頁面 -> myblog/demo_list.html """ rs = SimpleBlog.objects.all().values() return render( request, "myblog/demo_list.html", context={ "rs": rs, }, ) def get_one_blog_detail(request, b_id): """ 查看一篇博客 : "myblog/demo_detail.html" :param request: :param b_id: 點詳細信息時,傳過來的博客id 爲了不與id可能會發生二義性,故命名b_id :return: 查看某篇博客的內容 -> myblog/demo_detail.html """ rs = SimpleBlog.objects.get(id=int(b_id)) return render( request, "myblog/demo_detail.html", context={ "rs": rs, }, ) def update_one_blog(request, b_id): """ 修改一篇博客 :param request: :param b_id: :return: """ rs = SimpleBlog.objects.get(id=b_id) if request.method == "GET": return render( request, "myblog/demo_update.html", context={ "rs": rs, }, ) elif request.method == "POST": title = request.POST.get("title") content = request.POST.get("content") try: rs.blog_tilt = title rs.blog_content = content rs.save() # 爲了有update_time,才使用了這種方式 except Exception as e: return HttpResponse("修改時發生錯誤:" + e) else: return HttpResponse("修改爲功!") else: return HttpResponse("修改爲功!") def delete_one_blog(request, b_id): """ 刪除一篇博客 :param request: :param b_id: :return: """ try: SimpleBlog.objects.get(id=b_id).delete() except: return HttpResponse("沒有此篇博客") else: return redirect(reverse("blog_list")) # 直接重定向到列表頁面 # --------------- app:myblog 的邏輯 END ---------------
(五).註冊urls
# myblog/views.py from django.conf.urls import url from myblog import views urlpatterns = [ url(r"^$", views.index, name="myblog_index"), # 博客的首頁 url(r"^write_blog/$", views.write_blog, name="write_blog"), # 寫博客 url(r"^blog_list/$", views.get_all_blog_list, name="blog_list"), # 博客列表 url(r"^blog_detail/(?P<b_id>\d+)/$", views.get_one_blog_detail, name="blog_detail"), # 某篇博客的詳情 url(r"^delete_blog/(?P<b_id>\d+)", views.delete_one_blog, name="delete_blog"), # 刪除一篇博客 url(r"^update_blog/(?P<b_id>\d+)", views.update_one_blog, name="update_blog"), # 更新一遍博客 ]