模型方法关注点分离

时间:2019-04-16 03:28:33

标签: python django django-rest-framework

玩具示例:在我的Django项目中,我有两个应用程序:CoreBlog

Core 应用可为用户提供功能;用户模型,登录注销,注册等
博客应用程序提供博客功能;博客,评论,类别等

感兴趣的主题是模型:

# core/models.py

class User(models.Model):
    firstName = models.CharField(max_length=100)
    lastName = models.CharField(max_length=100)
    email = models.EmailField()
    ...

# blog/models.py

class BlogPost(models.model):
    title = models.CharField(max_length=100)
    post = models.TextField()
    owner = models.ForeignKey('core.User', on_delete=models.CASCADE)
    ...

我正在使用DRF并用于其中的一个ViewSet,在其中我为当前登录的用户返回了所有BlogPost的列表。为此,我需要创建一个QuerySet

我可以像这样在用户对象上创建模型方法:

# core/models.py

class User(models.Model):
    ...

    def viewable_blogs(self):
        return BlogPost.objects.filter(owner=self.id)

并像这样简单地使用它:

class BlogPostViewSet(viewsets.ModelViewSet):
    serializer_class = BlogPostSerializer

    def get_queryset(self):
        return self.request.user.viewable_blogs.all()

这对我来说似乎很不对劲,因为它违反了单一责任原则,所以让我有些不舒服。即用户模型应该对其他模型一无所知。

我来自其他框架,例如express,springboot等,我将创建一个BlogService并在其中放置viewable_blogs的功能:

class BlogPostViewSet(viewsets.ModelViewSet):
    serializer_class = BlogPostSerializer

    def get_queryset(self):
        return BlogService.getBlogsForUser(self.request.user)

是否有Django建议的方法来确保封装?使服务类成为Django的方法吗?

1 个答案:

答案 0 :(得分:2)

对于相关模型(即UserBlogPost),我认为Django会自动为您的RelatedManager实例创建一个User属性,blogpost_set

因此,您应该可以通过以下方式获取特定用户的博客文章:

user = User(pk=1)
user.blogpost_set.all()

这基本上与您在viewable_blogs方法中手动完成的功能相同,但是Django倾向于使用内置的“管理器”进行关系查询集。我会说创建BlogService可能不是理想的选择,因为它在模型之间的关系上增加了一层,而Python倾向于使用更简单的方法。

请参阅: