服务:使用django构建:创建blog应用
1 创建新应用,扩展api功能 -blog api,
新建posts 应用
python manage.py startapp posts
-
在全局setting注册
INSTALLED_APPS = ['posts.apps.PostsConfig', # blog api]
-
在全局路由 注册 posts路由
urlpatterns = [path('api/v1/', include('posts.urls')), # new]
-
App配置, 模型 models.py, 5个字段
# posts/models.py from django.db import models from django.contrib.auth.models import User class Post(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE) title = models.CharField(max_length=50) body = models.TextField() created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.title
-
App配置,在默认管理app中注册
from .models import Post # Register your models here. admin.site.register(Post)
1.1 PostsApp 路由配置
在app的 urls中,用户访问全局urls后,将被导向这里
# posts/urls.py
from django.urls import path
from .views import PostList, PostDetail
urlpatterns = [
path('<int:pk>/', PostDetail.as_view()),
path('', PostList.as_view()),
]
1.2 PostsApp 序列化操作
接口返回数据 Json 字段
序列化程序不仅可以将数据转换为JSON,还可以指定要包含或包含哪些字段,但是我们不想包含updated_at字段。
Django_REST_Framework强大的序列化程序类使控制变得非常简单。我们创建了一个PostSerializer,并在其中指定了一个Meta类包括哪些字段并明确设置要使用的模型。
有很多方法可以自定义序列化程序.
# posts/serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
fields = ('id', 'author', 'title', 'body', 'created_at',)
model = Post
1.3 PostsApp 视图配置
Views.py将 数据转发到 序列化模块
ListCreateAPIView,它类似于我们之前使用的ListAPIView,但允许写。
我们还希望使各个博客文章可供阅读,更新或删除。
确实,为此提供了一个内置的通用Django_REST_Framework视图用途:
RetrieveUpdateDestroyAPIView。
我们要做的就是更新我们的通用视图以从根本上改变给定API端点的行为。
所有这些功能都是可用的,经过测试的并且可以正常使用。不必在这里重新发明轮子。
此时api通过views视图的更改已经具有 CRUD功能。
# posts/views.py
from rest_framework import generics
from .models import Post
from .serializers import PostSerializer
-
可读写的视图
class PostList(generics.ListCreateAPIView): queryset = Post.objects.all() serializer_class = PostSerializer
-
可更新,删除的视图
class PostDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Post.objects.all() serializer\_class = PostSerializer
1.4 构建测试模块
我们访问测试客户端并发出GET请求。这模拟了您将使用浏览器发出的请求。注意网络服务器无需运行即可进行单元测试。这测试客户端直接与Django框架一起使用的.
# posts/tests.py
from django.test import TestCase
from django.contrib.auth.models import User
from .models import Post
class BlogTests(TestCase):
@classmethod
def setUpTestData(cls):
# Create a user
testuser1 = User.objects.create_user(
username='testuser1', password='abc123')
testuser1.save()
# Create a blog post
test_post = Post.objects.create(
author=testuser1, title='Blog title', body='Body content...')
test_post.save()
def test_blog_content(self):
post = Post.objects.get(id=1)
author = f'{post.author}'
title = f'{post.title}'
body = f'{post.body}'
self.assertEqual(author, 'testuser1')
self.assertEqual(title, 'Blog title')
self.assertEqual(body, 'Body content...')
1.5 迁移并重启服务
python manage.py makemigrations posts && python manage.py migrate && python manage.py runserver 0.0.0.0:2000
始终对API(v1/,v2/等)进行版本控制,因为更改API的各个使用者也可能需要一些时间才能更新。
那您可以在一段时间内支持API v1的方式,同时还启动新的,更新的v2并避免破坏依赖您API后端的其他应用。
小结
在django3中,一个项目中可以有多个应用,创建专用的api应用可能更有意义将所有其他API网址路由都包含进去。
但是对于像这样的基础项目,我宁愿避免仅用于路由的api应用。而是在我们需要时,我们随时可以添加一个。