DRF的基本用例似乎是“资源”(在API端)与表(在数据库端)之间存在一对一的映射。
具体来说,假设我们有一个包含一个或多个“项目”的“区域设置”实体:“区域设置”代表一组项目中的常见地理和管理信息 - 如果它更改为一个,我们需要更改为所有
我们在数据库中以Locale
和Projects
表格的形式表示,而不是将两者结合的非规范化Locale + Projects表,在我们的{中使用“Locale ID”作为外键{1}}表。但是,我们希望从api用户隐藏此规范化 - 我们只想公开Projects
端点,该端点返回与关联的/project/
数据连接的Project
数据,就好像它是来自非规范化表格。
如果在后端数据库中由多个模型(以及表格)组成,我如何在DRF中表示单个API资源?
技术说明:
(1) 在后端创建一个物化视图来执行连接,然后在Django中创建一个非托管模型,该模型存在以支持GET请求。
PROS :似乎与Django / DRF用例最佳网格,因为我只是 创建另一个表和模型(尽管具有只读功能)。
CONS :如果我想确保用户看到他们对基础数据的更改(例如,更改区域设置中的某些信息),我需要在每次更新后刷新实体化视图。我可能会同时使用REFRESH MATERIALIZED VIEW来至少允许视图在更新时起作用。
所以,+1表示易于实施,-1表示货币。
(2) 在后端使用原始参数化SQL查询来设置JOIN并返回结果。
PROS:避免在更新后刷新实体化视图时出现问题。
缺点:似乎很难适应复杂的问题 - 我发现这可能会变得脆弱。
(3)非规范化,因此我们有一个Locale
表
PROS:简单。
缺点:数据一致性受到损害。如果更改了区域设置记录,则需要编写其他后端查询来更新共享区域设置的记录。
任何其他输入都会有所帮助。
答案 0 :(得分:0)
我的建议是使用Project
模型作为基本模型,将Locale
相关字段用作补充字段。以下是ListAPIView
的示例。如果您需要创建或更新端点以同时更新Project
和Locale
,就像您有非规范化表一样,您可以覆盖create
和update
函数。
我认为locale
字段是从ForeignKey
到Project
的{{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