使用 DRF 和 DDD 构建 Django 项目
有很多方法可以构建 Django 项目。很难找到确保可维护性和可扩展性的设计。这是我的目标。
我一直在研究领域驱动设计以及如何将它与 Django REST 框架结合到 Django 中。我想设计一个健壮的架构,它易于记录,并且对协作和单独的项目都有效。不管我能否做到这一点,这次努力对我来说将是一次重要的经历。
该项目仍在进行中,DDD 中有一些我尚未完全探索的主题。我将尽我最大的努力研究它们,并希望在今年年底之前发布它的初始稳定版本。事不宜迟,让我们开始吧。
概述
这是初始结构:
project/
api/
migrations/
services/
blogs/
read_blog.py
__init__.py
apps.py
project/
__init__.py
asgi.py
settings.py
urls.py
wsgi.py
resources/
migrations/
repositories/
base_repository.py
blog_repository.py
serializers/
blog_serializer.py
__init__.py
admin.py
apps.py
models.py
进入全屏模式 退出全屏模式
目前,它拥有三个应用程序:api、project 和 resources。确保创建它们并安装djangorestframework和django-cors-headers软件包。
项目
项目文件夹是我们的核心应用程序。文件夹名称基于您为 django 项目输入的名称,因此您不必遵循本示例中提供的名称。默认情况下,这是存储设置、wsgi、asgi 和 url 的地方。我们还可以在此处存储其他文件,例如 JWT 的类、自定义中间件等。由于我们使用其他包,我们需要配置我们的设置文件:
项目/settings.py
INSTALLED_APPS = [
…
'corsheaders',
'rest_framework',
'api.apps.ApiConfig',
'resources.apps.ResourcesConfig',
]
MIDDLEWARE = [
…
'corsheaders.middleware.CorsMiddleware',
…
]
# this is set to true for now
CORS_ORIGIN_ALLOW_ALL = True
进入全屏模式 退出全屏模式
一旦我们建立了我们的 api 服务,我们稍后会重新访问这个文件夹。
资源
resources 文件夹是我们放置模型、存储库和序列化程序的地方。我们的模型将包含数据库表的模式,而我们的存储库将处理从持久层 (ORM) 获取对象。最后,序列化器会将我们的查询集呈现为 JSON。
资源/models.py
from django.contrib.auth.models import User
from django.db import models
class Blog(models.Model):
content = models.TextField()
summary = models.CharField(max_length=100)
title = models.CharField(max_length=100)
created_on = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
default=None
)
def __str__(self):
return self.title
进入全屏模式 退出全屏模式
对于我们的存储库,我们需要一个基本存储库文件,其中注册了所有基本方法,并且可以由不同的模型存储库继承。每个模型存储库都可以有自己的聚合和复杂查询方法:
资源/存储库/基础_repository.py
from django.db import InternalError, DatabaseError
from django.http import Http404, HttpResponseServerError
class BaseRepository(object):
def find(self, id, value_list=()):
try:
if len(value_list):
return self.model.objects.get(pk=id).values(*value_list)
else:
return self.model.objects.get(pk=id)
except self.model.DoesNotExist:
raise Http404
except InternalError:
raise HttpResponseServerError
except DatabaseError:
raise Http404
进入全屏模式 退出全屏模式
资源/存储库/博客_repository.rb
from resources.models import Blog
from resources.repositories.base_repository import BaseRepository
class BlogRepository(BaseRepository):
def __init__(self):
self.model = Blog
进入全屏模式 退出全屏模式
资源/序列化器/博客_serializer.py
from rest_framework import serializers
from resources.models import Blog
class BlogSerializer(serializers.ModelSerializer):
class Meta:
model = Blog
fields = [
'id',
'content'
'summary',
'title',
'created_on'
]
进入全屏模式 退出全屏模式
您可能想知道存储库的重要性是什么,因为我们已经有了 ORM。一个原因是这允许项目轻松迁移到不同的数据库,特别是如果 ORM 方法与默认 ORM 不同,或者如果数据库没有用于 Django 的 ORM 包。发生这种情况时,我们只需要更新存储库中的查询,而无需触及我们 api 中的服务。这是一个例子:
From RDBMS
ModelServices | ModelRepository
ModelRepository().find(id) | Model.objects.get(pk=id)
To NoSQL
ModelServices | ModelRepository
ModelRepository().find(id) | Model.find_one({"_id": id})
进入全屏模式 退出全屏模式
API
api 是存储我们端点的所有类视图的地方。目前,它只有 services 文件夹,其中存储了基于模型的子文件夹,并且每个子文件夹都有专门用于每个 CRUD 操作的文件。在这个例子中,我们有一个 blogs 文件夹和一个 read blog 文件,用于查看特定的 blog 记录:
api/services/blogs/read_blog.py
from rest_framework.views import APIView
from rest_framework.response import Response
from resources.repositories.blog_repository import BlogRepository
from resources.serializers.blog_serializer import BlogSerializer
class ReadBlogService(APIView):
def get(self, request, id, format=None):
blog = BlogRepository().find(id)
return Response(BlogSerializer(blog, many=False).data)
进入全屏模式 退出全屏模式
最终调整
现在,我们可以编辑 project.urls 文件来注册新的博客服务:
项目/urls.py
from django.contrib import admin
from django.urls import path
from api.services.blogs.read_blog import ReadBlogService
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/<int:id>', ReadBlogService.as_view()),
]
进入全屏模式 退出全屏模式
结论
这是我到目前为止所概念化的。它可能看起来很复杂,但那是因为它适用于中型和大型项目。它对小型应用程序没有用处。当然,我不认为这是 Django 程序员的理想选择。正如我之前提到的,有很多方法可以构建 Django 项目。毫无疑问,还有其他更好且经过实战考验的设计。但我会尽我最大的努力使它成为一个潜在的选择。
您对此有何看法?
更多推荐

所有评论(0)