【发布时间】:2021-08-14 11:16:17
【问题描述】:
我们的网站是一个 Vue 前端/DRF 后端。在serializer.validate() 方法中,我需要以编程方式确定TextChoices 类中的哪个选项已被指定为模型字段的默认值。
TextChoices 类(简例):
class PaymentMethod(models.TextChoices):
BANK_TRANSFER = 'Bank Transfer'
CREDIT_CARD = 'Credit Card'
PAYPAL = 'PayPal'
OTHER = 'Other'
型号:
class InvoicePayment(CommonFieldsModelMixin,
StatusFieldModelMixin,
models.Model):
...other fields omitted...
payment_method = models.TextField(
verbose_name=_('Method'),
choices=PaymentMethod.choices,
default=PaymentMethod.OTHER,
)
payment_method_other = models.TextField(
verbose_name=_('Payment Method Other'),
default='',
)
我们的用户能够绕过前端并直接发布到 API,这意味着他们可能会忽略 POST 数据中的字段 - 无论是由于疏忽还是因为字段具有默认值。但是,对于上述模型,仅当 payment_method 为“Other”时才需要 payment_method_other。该检查是在serializer.validate() 方法中完成的。
如果在前端的表单上选择“其他”,则没有问题,因为该值存在于传递给validate() 方法的validated_data 中。但是,如果用户直接向 API 发帖并省略了payment_method,则在执行validate() 方法之后,在数据库级别(或多或少)完成默认值处理。
为了保持 DRY,并避免在将来更改默认值时出现不匹配的代码,我不想在 validate() 方法中硬编码“Other”的默认值。相反,我想访问字段定义信息(元数据?)并以编程方式确定模型上定义的默认值。
【问题讨论】:
-
我添加了一个关于确定字段默认值的方法的答案。但是根据我对您对序列化程序的解释的了解,您无法处理省略
payment_method的情况?仍然可以通过检查该字段是否存在来在验证中进行检查? -
@bdbd,正确。如果我在
validated_data中找不到payment_metod,我知道我需要提供与 将提供 相同的默认值,因为它是在模型上定义的(我现在可以通过您的答案中非常简单的解决方案;谢谢)。然后,如果它恰好是“其他”,它将通过/失败验证,就像用户输入它一样。 -
好的,现在很清楚了。我只是在想,当它被省略时,你可以像
Other一样进行默认处理,就像payment_method一样,你不需要明确设置它,因为db会为你做。
标签: python django django-models django-rest-framework