良好的Django设计实践,以便在DRY之后添加REST api

问题描述 投票:2回答:1

我正在使用纯Django开始一个Web应用程序。但是,将来可能需要REST api。如果它发生,最明显的选择将是Django REST框架。

“老式”和REST部分共享模型,但是,视图略有不同(例如,权限定义),表单被序列化程序替换。以最明显的方式执行此操作意味着多次复制应用程序逻辑,因此无法遵循DRY原则,因此代码变得不可维护。

我有一个想法将所有逻辑写入模型(因为它们是共享的),但在这种情况下,将不会使用权限mixins,通用视图和代码将不是最好的。

现在我用完了想法。这里的最佳做法是什么?

django rest dry
1个回答
3
投票

我会尽量保持简单,因为您不确定API的未来需求,并且猜测会引入额外的复杂性,当需求明确时甚至可能不需要。

Django表单和Rest Framework序列化程序都已经为您提供了一种声明式方法,可以抽象出基本内容所需的样板代码,这些代码通常占据了大部分代码。例如,您的一个Django表单可能如下所示:

class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'content']

并且将来DRS序列化器将是:

class ArticleSerializer(ModelSerializer):
    class Meta:
        model = Article
        fields = ['title', 'content']

正如您所看到的,如果您尝试坚持使用ModelForm和ModelSerializer,那么无论如何都不会有太多重复。您还可以简单地将字段列表存储在变量中,然后重用它。

对于更多自定义事物,您可以从将逻辑共享到简单函数开始,例如:

def save_article_with_author(article_data, author_data):
    # custom data manipulation before saving, consider that article_data will be a dictionary either if it comes from deserialized JSON (api) or POST data
    # send email, whatever

此函数可以在表单和序列化程序之间共享。

对于与数据获取相关的所有内容,我尝试尽可能多地使用模型管理器,定义可以重新发送的自定义查询集,例如表单和序列化程序的选项。

我倾向于避免编写任何不直接读取或写入数据到模型类的逻辑。我认为与数据层的业务逻辑过多。例如,我从不想将任何身份验证/权限检查写入模型的save()方法,因为它会将不同的层耦合得太紧。

根据经验,想象一下这种情况:当创建用户创建覆盖文章模型的save()方法时,添加说权限检查或发送电子邮件的逻辑。然后,稍后您会被要求编写一个简单的管理命令,从电子表格批量导入用户。此时,您在save()方法中所做的事情确实会受到阻碍,因为您可以通过模型自由访问数据,而无需担心权限,电子邮件和所有这些。

关于视图层并假设您需要实现一些共享的身份验证/权限检查,并且您不希望拥有单独的视图,您可以使用以下方法:https://www.django-rest-framework.org/topics/html-and-forms/

Blockquote REST框架适用于返回API样式响应和常规HTML页面。此外,序列化程序可用作HTML表单并在模板中呈现。

以下是有关如何根据请求内容类型从HTML动态切换到JSON的一些指导原则:

https://www.django-rest-framework.org/api-guide/renderers/#advanced-renderer-usage

在你的情况下,这似乎是一个不错的选择,我会在你全力以赴之前写下一个快速的概念验证,看看你是否对你需要做的事情不太有限。

© www.soinside.com 2019 - 2024. All rights reserved.