使用Django Rest framework搭建Blog
在前面的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
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,并可以进行操作了.