Djangoåæ麼說ä¹æ¯å網é å¾ç«¯ï¼å¨ç¾å¨åå¾ç«¯åé¢ç趨å¢ä¹ä¸ï¼å¾ç«¯ä¸»è¦çåè½è®ææ¯å°è³æ庫é²è¡è«æ±ï¼ä¸¦å°çµæ以APIçæ¹å¼æä¾çµ¦å端é²è¡ç«é¢åç¾ãéç¶APIä¹å¯ä»¥æå»ï¼ä½ä¸åæ¼å¾çºçç¶è·ï¼ä¸å®å ¨é¨åéè¦èéã æ¬ç¯æç« å°è¦çºæ¨è©³è¿°Djangoç強大å¥ä»¶rest_frameworkåè½è使ç¨æ¹å¼ï¼è®éåDjangoå¾ç«¯çåè½å®æ´ï¼
å®è£çæ¹å¼é常簡å®ï¼å¨çµç«¯æ©ä½¿ç¨pipé²è¡å®è£å³å¯ï¼å°±è·å®è£ä¸è¬çPythonå¥ä»¶æ²ä»éº¼å ©æ¨£ãçè æå®è£ççæ¬æ¯ 3.14.0ççæ¬ï¼ç®åæ¯éæ²æ碰å°ä¸åçæ¬æé æçç¸éåé¡ã
pip install djangorestframework
æéè¦çæ¯å¨INSTALLED_APPS
åæ¸ç¶ä¸ï¼å å
¥rest_framework
ï¼å¦ä¸æ示ï¼
INSTALLED_APPS = [
'django.contrib.admin', # 管çè
å¾å°
'django.contrib.auth', # èªèææ¬ç®¡ç
'django.contrib.contenttypes', # å
§å®¹é¡å管ç
'django.contrib.sessions', # session 管ç
'django.contrib.messages', # è¨æ¯ç®¡ç
'django.contrib.staticfiles', # éæ
æªæ¡ç®¡ç
'myapp',
'rest_framework' # å ä¸ä»
]
以ä¸å¯è¨å®ï¼å¯ä¸è¨å®
å
¶å¯¦é以ä¸éä¸æ¥Rest Frameworkå°±å¯ä»¥ä½¿ç¨äºï¼ä½å¦ææ³è¦å°APIé²è¡ä¸äºç´°é¨çè¨å®ï¼å¥ä»¶ä¹æ¯ææä¾çåï¼æ¬æå°±ä¾ç
§å¸¸ç¨çAPIè¨è¨ä¾å»ºæ§ç¯ä¾ï¼å»ºé REST_FRAMEWORK
éååæ¸ãREST_FRAMEWORK
éååæ¸åæ¬å¨settings.py
æªæ¡ä¸ä¸¦æ²æï¼å æ¤è¦åsettings.py
æ¾å空ç½èèªå·±æ°å¢REST_FRAMEWORK
è®æ¸åï¼
REST_FRAMEWORK = {
"PAGE_SIZE": 100,
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
'DEFAULT_PARSER_CLASSES': ['rest_framework.parsers.JSONParser'],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication",
"rest_framework.authentication.TokenAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],
}
é裡ä¹çºåæ¸çå §é¨è¨å®ä½ä»ç´¹ï¼
åæ¸å稱 | 說æ |
---|---|
PAGE_SIZE | List API æ¯æ´åé æï¼æ¯é åªå³å 100 ç |
DEFAULT_PAGINATION_CLASS | èPAGE_SIZEåæ¸æé 使ç¨ãåé çåæ¸æ¯ä½¿ç¨ limit è· offset |
DEFAULT_PARSER_CLASSES | åªå 許 Content-Type æ¯ application/json |
DEFAULT_AUTHENTICATION_CLASSES | é©èæ¹å¼æ¯ä½¿ç¨ Session è· Token |
DEFAULT_PERMISSION_CLASSES | æ¬éæ¯è¦æ±å¿ é è¦é©èéæè½å¼å« API |
éè¦å¨è³æ夾myapp
ä¸å»ºç«ä¸åæ°æªæ¡serializers.py
ï¼æªæ¡å
§å®¹å¦ä¸ï¼
from rest_framework import serializers
from .models import Article, Classification
class ArticleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Article
fields = [
'id',
'title',
'language',
'classification_id',
'number',
'video_url']
class ClassificationSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Classification
fields = ['id','title', 'created_time']
ä¸è¬ä¾èªªAPI並ä¸æå°ææè³æ表ä¸çæ¬ä½é¡¯ç¤ºï¼åªéè¦æ¥é²ç®ç端æéè¦çæ¬ä½å°±å¥½ãå æ¤éåé¨å主è¦æ¯è¨å®ï¼ç¶APIè«æ±æï¼è¦ä¸åºåªå¹¾åæ¬ä½ã
ä¹å æ¤çè
å¨ArticleSerializer
ç©ä»¶ä¸ï¼å»æä¸è¼¸åºcreated_time
éåæ¬ä½ï¼å°±æ¯è¦åæ¨èªªæï¼è¥è©²æ¬ä½æ²å¿
è¦è¼¸åºï¼å¯ä»¥å¨é裡就æé¤æã
æ¥èå¨è³æ夾myapp
ä¸å»ºç«ä¸åæ°æªæ¡viewsets.py
ï¼æªæ¡å
§å®¹å¦ä¸ï¼
from rest_framework import viewsets, status
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.decorators import action
from .models import Article, Classification
from .serializers import ArticleSerializer, ClassificationSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
permission_classes = [AllowAny]
class ClassificationViewSet(viewsets.ModelViewSet):
queryset = Classification.objects.all()
serializer_class = ClassificationSerializer
permission_classes = [AllowAny]
æ¤èå¼ç¨äºåä¸æ¥çserializers.py
æªæ¡ï¼ä¸»è¦æ¯è¨å®è«æ±çç¸éåæ¸ï¼
è¥æ¨åªæ¯å試使ç¨Rest Frameworkï¼åæè å æ±è½å·è¡ç話ï¼éåæ¥é©å¯ä»¥è·³éãæ¬æ¥é©æå¨é²è¡ä¸äºæ¬éè¨å®ãè³æå §å®¹ç¯©é¸çåè½å¤å說æã
æåä¿®æ¹ååè¨å®å¥½çArticleViewSet
ç©ä»¶ãé¦å
åªé¤permission_classes = [AllowAny]
éä¸è¡ï¼æ¢ç¶è¦æ¬éæ§ç®¡ï¼çµå°ä¸å¯è½ææè«æ±å
¨é¨æ¾è¡ãæ¥èå å
¥get_permissions
æ¹æ³ï¼å®æ´ç©ä»¶å
§å®¹å¦ä¸ï¼
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
def get_permissions(self):
if self.action in ('create',):
self.permission_classes = [IsAuthenticated]
else:
self.permission_classes = [AllowAny]
return [permission() for permission in self.permission_classes]
å¨æ¤æ¹æ³ä¸æª¢æ¸¬è«æ±è¥çºcreate
ï¼ä»£è¡¨æ¯æ°å¢è³æçåä½ï¼é£å°±éè¦æª¢æ¥æ¬éï¼å¦åä¸æ人士é½å¯ä»¥å¨æ¨çè³æ庫ä¸æ³¨å
¥è³æäºãèå
¶ä»è«æ±åæ¯å¯æ¾è¡ï¼è®ä¸è¬çæ¥çæ¬éæ¯éçï¼
æ¥çºååçæ¬éæ§ç®¡ãè¥æåæ³è¦å¨APIä¸å©ç¨æå®çåæ¸ï¼å¨è³æ庫ä¸ç¯©é¸å¾æç¨API輸åºåºä¾å¯ä»¥æ麼åå¢ï¼
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
permission_classes = [AllowAny]
# æé¸ææç« é¡å¥
@action(detail=True, methods=['get'])
def pick_classify(self, request, pk=None):
serializer = ArticleSerializer(
Article.objects.filter(classification_id = pk),
many=True,context={'request': request})
return Response(serializer.data, status=status.HTTP_200_OK)
APIç¶ä¸ææ¥æ¶pk
éååæ¸ï¼ä¸¦è¼¸å
¥å°filter()
éåæ¹æ³é²è¡è³æ庫ç篩é¸ï¼é¡ä¼¼æ¼SQLèæ³ä¸çwhere
æ¦å¿µãå¦æ¤ä¸ä¾ä¾¿å¯ä»¥å©ç¨APIæå®ç¹å®è³æäºã
http://127.0.0.1:8000/api/articles/{åæ¸}/pick_classify/
å¨myweb/urls.py
æªæ¡ä¸å å
¥å
§å®¹ï¼
from django.contrib import admin
from django.urls import path
from myapp import views
from myapp.viewsets import ArticleViewSet, ClassificationViewSet # å å
¥éè¡
from rest_framework.routers import DefaultRouter # å å
¥éè¡
from django.urls import path, include # å å
¥éè¡
router = DefaultRouter() # å å
¥éè¡
router.register(r'articles', ArticleViewSet, basename='article') # å å
¥éè¡
router.register(r'classification', ClassificationViewSet, basename='classification') # å å
¥éè¡
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.test),
path("api/", include(router.urls)),# å å
¥éè¡
]
ç¨python manager.py runserver
éåserver å¾ï¼å¯ä»¥å°http://127.0.0.1:8000/api/articles/æhttp://127.0.0.1:8000/api/classification/æ¥çååæè¨å®çAPIã
è³æ¤å ¶å¯¦å·²ç¶å¯ä»¥ä½¿ç¨APIäºãä½å¨å¯¦éçåå¾ç«¯ç¶²ç«ä½¿ç¨ä¸æç¼ç¾ä¸ååé¡ï¼è«æ±æ¬¡æ¸éå¤ãè°æçæ¨æç¼ç¾ï¼ååçAPIè¨è¨å ¶å¯¦é½æ¯åç¹èè³æ表é²è¡è¼¸åºï¼ä½å¾å¤æåå端è¦çè³æï¼æ¯éè¦å¤å¼µè¡¨çç¶åè³æï¼ä¸¦ä¸éææé層éä¿ã
就已ç¯ä¾èä¾ï¼æåæå ©åè³æ表Article(æç« )èClassification(åé¡)ï¼å¦ææå¨å端åç¾ä»¥ä¸è³æï¼
{
'åé¡1':['Aæç« '],
'åé¡2':['Bæç« ','Cæç« ']....
}
以ä¸çè³æå¿ é è¦åå¥è«æ±è³æ表Article(æç« )èClassification(åé¡)ï¼èå端æ¶å°è³æå¾ééè¦åé²è¡æ´çã
è¥çºå°æ¥çå¾ç«¯äººå¡ï¼æ¯æåå¦å¤å»ºç«ä¸åè³æ表å®æçºå ©åè³æ表åæ´çï¼å¦æ¤å¯æé«è«æ±æçãåæè æåæ³è¦å¨å¾ç«¯Djangoçé¨åå°±èçå®æå¢ï¼
å¨æªæ¡myapp/views.py
ç¶ä¸ï¼æ°å¢chapter()
æ¹æ³ï¼æ¹æ³å
§å¤çºè³ææ´ççé¨åï¼åªæ¯åç¯ä¾ä¸¦ä¸å¤å解éï¼
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from .models import Article, Classification
from rest_framework.response import Response
from rest_framework import status
# Create your views here.
def test(request):
return render(request, 'test.html', {
'title': '測試',
'data' : 'é裡æ¯æ¨é¡'
})
#---------- èªè¨API ----------
class chapter(APIView):
permission_classes = [AllowAny]
def get(self, request):
Classification_data = Classification.objects.all()
data = {}
for cls in Classification_data:
Article_data = Article.objects.filter(classification_id = cls.id)
temp_array = []
for atc in Article_data:
temp_array.append(atc.title)
data[cls.id] =temp_array
return Response(data, status=status.HTTP_200_OK)
from django.contrib import admin
from django.urls import path
from myapp import views
from myapp.viewsets import ArticleViewSet, ClassificationViewSet
from rest_framework.routers import DefaultRouter
from django.urls import path, include
router = DefaultRouter()
router.register(r'articles', ArticleViewSet, basename='article')
router.register(r'classification', ClassificationViewSet, basename='classification')
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.test),
path("api/", include(router.urls)),
path('chapter/', views.chapter.as_view()),# å å
¥éè¡
]
å¦æ¤ä¸ä¾å¨é²å ¥http://127.0.0.1:8000/chapter/å¾ï¼ä¾¿å¯ä»¥çå°å®¢è£½åAPIçææäºï¼
Rest Frameworkç模å¼ï¼æ¯ç®åå¾ç«¯APIè¨è¨æ常æ¡ç¨çï¼æäºDjangoçå¥ä»¶æ¯æè®æåå¨å»ºç«APIçäºåä¸äºåååãè實éä¸å¨ä½¿ç¨APIçæåæç¼ç¾ï¼ææ使ç¨Postman試èææçAPIï¼å»æä¸å°è³æï¼ä¸¦ä¸ç覽å¨çconsoleä¸æ顯示以ä¸é¯èª¤ï¼
cors error: the request has been blocked because of the cors policy
åæè å°Djangoçå¾ç«¯æåå®æå¾ï¼ä¸ä¸å»é²ç«¯ç©ºéå¾ï¼ç»å ¥å»åºç¾äºãCSRF é©è失æãï¼éäºåé¡å°å¨ä¸ç¯æç« ããäºé¨æ²ãPythonæç«ç´ æ¡æ¶Djangoï¼CORSèCSRFé¯èª¤æ麼æé¤?ãçºæ¨è§£æã
作者:楊超霆 行銷搬進大程式 創辦人