DRF:提供动态默认字段值的最佳方式?
Posted
技术标签:
【中文标题】DRF:提供动态默认字段值的最佳方式?【英文标题】:DRF: Best way to supply a dynamic default field value? 【发布时间】:2020-04-30 13:48:52 【问题描述】:我们的 SAAS 站点使用 DRF 后端和 Vue 前端。我们的字段不需要用户提供值,但需要数据库中的值。我想知道提供这种动态默认值的最佳位置在哪里。我在其他帖子中读到“并不总是调用 save()”——尽管我还不知道在什么情况下不会调用它。
因此,请考虑以下模型:
class Tenant(models.Model):
name = models.CharField(max_length=100)
subdomain = models.CharField(max_length=100, blank=True, null=True)
schema_name = models.CharField(max_length=63, unique=True)
在这种情况下,只需要“姓名”(来自用户); “schema_name”,如果在前端表单中留空,可以从“name”派生(将其转换为小写)。同样,“子域”可以从“schema_name”派生。 “子域”可以为空/null,因为“公共”架构不引用子域,但“公共”以外的所有租户都需要其值。)
那么在创建或更新租户时,如果这些字段为空白,我应该将填充这些字段的代码放在哪里?
【问题讨论】:
【参考方案1】:除非您进行批量更新,否则将调用保存,因此您可以将其放在那里就好了。如果有选择,我不喜欢,但有时没有。
如果要放到序列化器中,可以这样写,然后用ModelViewSet
处理细节:
class TenantSerializer(ModelSerializer):
name = CharField(required=True, min_length=1)
sub_domain = CharField(required=False)
class Meta:
model = Tenant
fields = ['id', 'name', 'sub_domain']
def validate(self, attrs):
# attrs is all fields parsed & validated on a per-field level
# in here you can do validation that depends on >1 field
# values returned will be passed to the serializer create()/update()
# via the common serializer.save() method
if self.instance:
# doing an update, maybe different logic, or just ignore?
else:
if not attrs.get('sub_domain'): # missing or blank
attrs['sub_domain'] = parse_subdomain(attrs.get('name'))
return attrs
【讨论】:
为什么你“如果有选择不喜欢”?除了您在答案中显示的序列化程序之外,还有哪些选择? 这只是一个偏好,在少数情况下我确实有“保存”逻辑,但是......随着串行器做各种工作,我发现它变得令人困惑,因为有很多逻辑许多序列化程序。我也在为多个位置修改的模型上使用的另一种方法是signals
,通常是pre_save
。最糟糕的是有两个地方都做复杂的逻辑和试图找出交互。赞成“最少的惊喜”,所见即所得。您还可以覆盖与MyModel.objects
关联的ModelManager
上的create
方法以上是关于DRF:提供动态默认字段值的最佳方式?的主要内容,如果未能解决你的问题,请参考以下文章