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:提供动态默认字段值的最佳方式?的主要内容,如果未能解决你的问题,请参考以下文章

哪种是存储 Firebase 远程配置默认值的最佳方式?

hive使用动态分区时如果动态分区的字段存在空值的问题

Oracle中插入默认时间

drf的序列化和反序列化

设置应该是 Python 列表的参数的默认值的最佳实践?

Vue:为数组属性设置默认值的最佳方法?