将Django Rest Framework与规范化数据库一起使用

时间:2018-02-02 17:30:34

标签: rest django-models django-rest-framework relational-database

DRF的基本用例似乎是“资源”(在API端)与表(在数据库端)之间存在一对一的映射。

具体来说,假设我们有一个包含一个或多个“项目”的“区域设置”实体:“区域设置”代表一组项目中的常见地理和管理信息 - 如果它更改为一个,我们需要更改为所有

我们在数据库中以LocaleProjects表格的形式表示,而不是将两者结合的非规范化Locale + Projects表,在我们的{中使用“Locale ID”作为外键{1}}表。但是,我们希望从api用户隐藏此规范化 - 我们只想公开Projects端点,该端点返回与关联的/project/数据连接的Project数据,就好像它是来自非规范化表格。

如果在后端数据库中由多个模型(以及表格)组成,我如何在DRF中表示单个API资源?

技术说明

  • 我在posgtresql 9.6中的后端
  • 这不是交易数据库,所以我们希望每天更新10-15个订单,而不是每秒100个。

到目前为止我的想法

(1) 在后端创建一个物化视图来执行连接,然后在Django中创建一个非托管模型,该模型存在以支持GET请求。

PROS :似乎与Django / DRF用例最佳网格,因为我只是     创建另一个表和模型(尽管具有只读功能)。

CONS :如果我想确保用户看到他们对基础数据的更改(例如,更改区域设置中的某些信息),我需要在每次更新后刷新实体化视图。我可能会同时使用REFRESH MATERIALIZED VIEW来至少允许视图在更新时起作用。

所以,+1表示易于实施,-1表示货币。

(2) 在后端使用原始参数化SQL查询来设置JOIN并返回结果。

PROS:避免在更新后刷新实体化视图时出现问题。

缺点:似乎很难适应复杂的问题 - 我发现这可能会变得脆弱。

(3)非规范化,因此我们有一个Locale

PROS:简单。

缺点:数据一致性受到损害。如果更改了区域设置记录,则需要编写其他后端查询来更新共享区域设置的记录。

任何其他输入都会有所帮助。

1 个答案:

答案 0 :(得分:0)

我的建议是使用Project模型作为基本模型,将Locale相关字段用作补充字段。以下是ListAPIView的示例。如果您需要创建或更新端点以同时更新ProjectLocale,就像您有非规范化表一样,您可以覆盖createupdate函数。

我认为locale字段是从ForeignKeyProject的{​​{1}}。

Locale

serializers.py

class ProjectWithLocaleSerializer(serializers.ModelSerializer): locale_field_1 = serializers.XXXField(source='locale.field_1') locale_field_2 = serializers.XXXField(source='locale.field_2') class Meta: model = Project fields = ('project_field_1', 'project_field_2', 'locale_field_1', 'locale_field_2', )

views.py