使用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,并可以进行操作了.

 

 

posted @ 2023-04-19 16:30  magicduan  阅读(79)  评论(0编辑  收藏  举报