使用Django開發簡單介面:文章增刪改查
目錄
- 1、一些準備工作
- 安裝django
- 建立django專案
- 建立部落格應用(app)
- 2、models.py
- 3、django admin
- 登入
- 建立超級使用者
- 4、修改urls.py
- 5、新增文章介面
- 6、查詢文章介面
- 7、修改文章介面
- 8、刪除文章介面
- 9、鑑權
- 鑑權介面
- 使用者認證
1、一些準備工作
安裝django
pip install django
建立django專案
進入專案程式碼存放目錄執行命令:
django-admin.py startproject blog_demo
進入blog_demo,執行命令:
python3.6 manage.py runserver 9000
在瀏覽器位址列開啟:http://127.0.0.1:9000/ 如果出現以下畫面,則說明伺服器正在執行
建立部落格應用(app)
django中每一個app可以看作是一個模組,以app為單位,結構清晰,方便管理。
python3.6 manage.py startapp blog_api
使用開發工具開啟專案blog_demo,其結構如下:
2、models.py
編寫模型層程式碼,以下語句相當於建立了兩張表:User,Article
class User(models.Model): id = models.AutoField(primary_key=True) uname = models.CharField(max_length=50) upwd = models.CharField(max_length=100) #active inactive status = models.CharField(max_length=10) class Article(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=50) content = models.TextField() #deleted alive status = models.CharField(max_length=10)
建立表結構:
python3.6 manage.py migrate
settings.py檔案INSTALLED_APPS處新增app:blog_api
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog_api'
]
讓django知道模型有了變化:
python3.6 manage.py makemigrations blog_api
再次建立表結構:
python3.6 manage.py migrate
3、django admin
登入
在瀏覽器控制檯輸入:http://127.0.0.1:9000/admin/login/?next=/admin/
建立超級使用者
stephen@stephen-K55VD:~/IdeaProjects/blog_demo$ python3.6 manage.py createsuperuser
Username (leave blank to use 'stephen'): admin
Email address:
Password:
Password (again):
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
郵件地址可以不填,註冊成功後即可登入。使用admin後臺來管理模型需要先註冊,修改blog_api/admin.py程式碼
#匯入模型User,Article
from blog_api.models import User,Article
admin.site.register(User)
admin.site.register(Article)
重新整理admin後臺,就可以看到剛剛註冊的模型了。
4、修改urls.py
from blog_api.views import add_article,modify_article
urlpatterns = [
path('admin/', admin.site.urls),
path('articles/',add_article),
path('articles/<int:art_id>',modify_article)
]
5、新增文章介面
from django.http import HttpResponse,JsonResponse
from blog_api.models import User,Article
import json
#新增文章
def add_article(request):
if request.method == "POST":
req = json.loads(request.body)
print (req)
key_flag = req.get("title") and req.get("content") and len(req)==2
#判斷請求體是否正確
if key_flag:
title = req["title"]
content = req["content"]
#title返回的是一個list
title_exist = Article.objects.filter(title=title)
#判斷是否存在同名title
if len(title_exist) != 0:
return JsonResponse({"status":"BS.400","msg":"title aleady exist,fail to publish."})
'''插入資料'''
add_art = Article(title=title,content=content,status="alive")
add_art.save()
return JsonResponse({"status":"BS.200","msg":"publish article sucess."})
else:
return JsonResponse({"status":"BS.400","message":"please check param."})
使用postman工具呼叫介面,執行結果:
6、查詢文章介面
#查詢所有文章和狀態
if request.method == "GET":
articles = {}
query_art = Article.objects.all()
for title in query_art:
articles[title.title] = title.status
return JsonResponse({"status":"BS.200","all_titles":articles,"msg":"query articles sucess."})
執行結果:
7、修改文章介面
#修改文章
def modify_article(request,art_id):
if request.method == "POST":
req = json.loads(request.body)
try:
art = Article.objects.get(id=art_id)
key_flag = req.get("title") and req.get("content") and len(req)==2
if key_flag:
title = req["title"]
content = req["content"]
title_exist = Article.objects.filter(title=title)
if len(title_exist) > 1:
return JsonResponse({"status":"BS.400","msg":"title aleady exist."})
'''更新資料'''
old_art = Article.objects.get(id=art_id)
old_art.title = title
old_art.content = content
old_art.save()
return JsonResponse({"status":"BS.200","msg":"modify article sucess."})
except Article.DoesNotExist:
return JsonResponse({"status":"BS.300","msg":"article is not exists,fail to modify."})
執行結果:
8、刪除文章介面
#刪除文章
if request.method == "DELETE":
try:
art = Article.objects.get(id=art_id)
art_id = art.id
art.delete()
return JsonResponse({"status":"BS.200","msg":"delete article sucess."})
except Article.DoesNotExist:
return JsonResponse({"status":"BS.300","msg":"article is not exists,fail to delete."})
執行結果:
9、鑑權
四個簡單的介面已經可以運行了,但是在發請求之前沒有進行鑑權,毫無安全性可言。下面來實現簡單的認證機制。需要用到內建模組hashlib,hashlib提供了常見的摘要演算法,如MD5,SHA1等。
鑑權介面
新增一個專門用於鑑權的介面。在urls.py中新增
path("auth/",get_token)
在views.py前面新增函式get_token(request)
import hashlib
#獲取token
def get_token(request):
req = json.loads(request.body)
uname = req["username"]
upwd = req["password"]
if request.method == "POST":
try:
tmppwd =User.objects.get(uname=uname).upwd
if upwd == tmppwd:
md5 = hashlib.md5()
#把密碼變成一個長度固定的字串
md5.update(upwd.encode("utf-8"))
return JsonResponse({"status":"BS.201","X-Token":md5.hexdigest()})
else:
return JsonResponse({"status":"BS.401","msg":"username or password may wrong."})
except User.DoesNotExist:
return JsonResponse({"status":"BS.500","msg":"username is not exist."})
登入django admin在blog_api下的User表新增一條記錄。執行結果:
使用者認證
request.META.get(“header key”) 用於獲取header的資訊。注意的是header key必須增加字首HTTP,同時大寫,中劃先會轉成下劃線,例如你的key為X-Token,那麼應該寫成request.META.get("HTTP_X_TOKEN"),修改views.py在get_token後面加上如下程式碼:
#認證動作
def user_auth(request):
token = request.META.get("HTTP_X_TOKEN",b'')
print (token)
if token:
#暫時先寫上auth介面返回的資料
if token=="0a6db4e59c7fff2b2b94a297e2e5632e":
return "auth_sucess"
else:
return "auth_fail"
else:
return "auth_fail"
在介面中呼叫user_auth函式,以釋出文章介面為例:
#新增文章
def add_article(request):
auth_res = user_auth(request)
if auth_res == "auth_fail":
return JsonResponse({"status":"BS.401","msg":"user auth failed."})
else:
if request.method == "POST":
req = json.loads(request.body)
print (req)
.......
再次使用postman工具呼叫新增文章介面,Header中沒有X-Token或X-Token錯誤時的執行結果: