我需要检查 unique_together 只有在两个字段都提供给管理员创建 Form 或通过 API 请求两个 create 和 update 调用。如果发生这种情况并且字段不是 unique_together 我需要将 Exception 传播到 django-admin 创建 Form 和 RestFramework 的 Serializer/ViewSet。
这是我的模型的一个简化示例:
class MyModel(models.Model):
time = models.TimeField(null=True, blank=True)
date = models.DateField(null=True, blank=True)
some_other_field = models.BooleanField(default=False)
...
正如您在模型级别看到的那样,time 和 date 都不是必需的并且可以为 null。
另一方面,应用程序逻辑要求至少提供这些字段中的一个,如果同时提供这两个字段——这对对于整个表来说应该是唯一的,以避免 datetime 组合的重复。
此模型通过以下节点访问:django-admin 和 DjangoRestFramework 使用 ViewSet 的端点。
从 API 的角度来看,创建新记录似乎不是问题,我可以覆盖 Serializer 的 validate 方法:
def validate(self, data):
if not data.get('time') and not data.get('date'):
raise serializers.ValidationError(
"At least one of this fields is required: time, date"
)
if OpenTable.objects.filter(
time=data.get('time'),
date=data.get('date')).exists():
raise serializers.ValidationError('Duplicates for date or datetime not allowed')
return data
但是当我收到 PUT 或 PATCH 请求时,这就变成了一个问题,因为尽管这条记录是表中唯一的记录,但我引发了 ValidationError 恰恰是因为有一条包含此 date-time 对的记录。
覆盖 validate 方法也没有解决阻止从 Django-Admin 创建这样的对的问题。
目前我最接近验证的是使用 MyModel 的 save 方法,但我不明白如何在那里处理这种情况以符合创建/更新流程。
请您参考如下方法:
对于 Django Rest Framework 验证,您可以使用 self.instance 检查来使用不同的验证流程来创建和修改对象;
def validate(self, data):
if self.instance:
# Modifiying an existing instance, run validations accordingly
else:
# Creading a new instance, run validations accordingly
对于管理站点,您可以使用 Django 的 ModelForm 结构及其验证来强制执行管理站点的验证。您需要将您的管理站点设置为使用您的 MyModel
自定义表单