- A+
在前面的Blog例子中我们使用的是GraphQL, 虽然GraphQL的使用处于上升趋势,但是Rest API还是使用的更广泛一些.
所以还是决定回到传统的rest api framework上来, Django rest framework的官网上给了一个很好用的QuickStart, 我参考Quick Start将前面的Blog的例子用DRF(Django Rest Framework)重新构筑一遍.
搭建Blog的rest api server
创建Blog Django project
安装DRF(Django Rest Framework)
pip install djangorestframework
创建Blog Project
django-admin startproject drf_backend
cd drf_backend
django-admin startapp blog
cd ..
python manage.py migrate #创建缺省的sqlite数据库
python manage.py createsuperuser #创建super user
python manage.py runserver #启动服务
上述操作后可以进入http://127.0.0.1:8000/admin 查看服务
创建Blog Models
参考前面Blog的代码在models.py加入 Post, Tag, Profile的Model代码
在admin.py中加入缺省的管理页面,
blog/models.py
from django.db import models from django.conf import settings # Create your models here. class Profile(models.Model): user = models.OneToOneField( settings.AUTH_USER_MODEL, on_delete=models.PROTECT, ) website = models.URLField(blank=True) bio = models.CharField(max_length=240, blank=True) def __str__(self): return self.user.get_username() class Tag(models.Model): name = models.CharField(max_length=50, unique=True) def __str__(self): return self.name class Post(models.Model): class Meta: ordering = ["-publish_date"] title = models.CharField(max_length=255, unique=True) subtitle = models.CharField(max_length=255, blank=True) slug = models.SlugField(max_length=255, unique=True) body = models.TextField() meta_description = models.CharField(max_length=150, blank=True) date_created = models.DateTimeField(auto_now_add=True) date_modified = models.DateTimeField(auto_now=True) publish_date = models.DateTimeField(blank=True, null=True) published = models.BooleanField(default=False) author = models.ForeignKey(Profile, on_delete=models.PROTECT) tags = models.ManyToManyField(Tag, blank=True)
blog/admin.py
from django.contrib import admin from blog.models import Profile, Post, Tag # Register your models here. @admin.register(Profile) class ProfileAdmin(admin.ModelAdmin): model = Profile @admin.register(Tag) class TagAdmin(admin.ModelAdmin): model = Tag @admin.register(Post) class PostAdmin(admin.ModelAdmin): model = Post list_display = ( "id", "title", "subtitle", "slug", "publish_date", "published", ) list_filter = ( "published", "publish_date", ) list_editable = ( "title", "subtitle", "slug", "publish_date", "published", ) search_fields = ( "title", "subtitle", "slug", "body", ) prepopulated_fields = { "slug": ( "title", "subtitle", ) } date_hierarchy = "publish_date" save_on_top = True
构造数据库
python manage.py makemigrations python manage.py migrate
数据Serializers
创建 blog/serializers.py, 这里我们使用HyperlinkedModelSerializer 类, 也可以使用ModelSerializer. 这两者的区别在于HyperLinkedModelSerializer将id直接变成url形式,这样可以不用在代码中再构造url.
from blog.models import Post,Tag,Profile from django.contrib.auth.models import User from rest_framework import serializers class PostSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Post fields = ['url','title','subtitle','slug','body','meta_description','date_created','publish_date','published','author','tags'] class TagSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Tag fields = ['url','name'] class ProfileSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Profile fields = ['url','profile_pic','bio','user'] class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ['url','username','email','password']
Views
对应的rest api的请求,我们在blog/views.py中加入相关的处理
from django.shortcuts import render from django.contrib.auth.models import User from blog.models import Post,Tag,Profile from rest_framework import viewsets,permissions from blog.serializers import PostSerializer,TagSerializer,ProfileSerializer class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all().order_by('publish_date') serializer_class = PostSerializer # permission_classes = [permissions.IsAuthenticated] class TagViewSet(viewsets.ModelViewSet): queryset = Tag.objects.all() serializer_class = TagSerializer class ProfileViewSet(viewsets.ModelViewSet): queryset = Profile.objects.all() serializer_class = ProfileSerializer
*注意我们这里先不使用permission_classes,如果使用的话,在浏览器上就必须Login才能取得对应的数据
配置URL
在drf_backend/urls.py加入下列代码
from django.contrib import admin from django.urls import path,include from rest_framework import routers from blog import views router =routers.DefaultRouter() router.register(r'posts', views.PostViewSet) router.register(r'tags',views.TagViewSet) router.register(r'profile', views.ProfileViewSet) urlpatterns = [ path('admin/', admin.site.urls), path('api/', include(router.urls)), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) ]
配置drf_backend/settings/py
INSTALLED_APPS = [ ... "corsheaders", 'rest_framework', 'blog', ]
Pagination (配置Rest API取得每页的数据数)
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10 }
配置可以访问的Frontend的地址和端口
CORS_ORIGIN_ALLOW_ALL = False CORS_ORIGIN_WHITELIST = ("http://localhost:8080",)
在浏览器中进入http://localhost:8000/api/ 可以看到Server提供的rest api的相关url,并可以进行操作了.