只有在两个字段都提供给管理员创建Form
或通过API
请求create
和update
调用的情况下,我才需要检查unique_together
。如果发生这种情况,并且字段不是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
和使用ViewSet
的DjangoRestFramework
的端点。
从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
。
重写CCD_ 26方法也不能解决阻止从CCD_ 27创建这样的对的问题。
目前,我最接近于验证这一点的是使用MyModel
的save
方法,但我不知道如何准确地处理这种情况,以符合create
/update
流程。
对于Django Rest Framework验证,您可以使用self.instance check来使用不同的验证流来创建和修改对象;
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的自定义表单