在从2.4.4升级到Django REST Framework 3.0的过程中,我希望有一个只读用户字段,但这是失败的,因为' user' UniqueTogetherValidator(我认为)
需要我有模型(借口错别字,这是简化的,代码工作正常IRL):
class ExampleModel(models.Model):
some_attr = models.PositiveSmallIntegerField()
other_attr = models.PositiveSmallIntegerField()
user = models.ForeignKey(User)
class Meta:
unique_together = ('some_attr', 'other_attr', 'user')
视图集:
class ExampleViewSet(viewsets.ModelViewSet):
queryset = ExampleModel.objects.all()
serializer_class = ExampleSerializer
def perform_create(self, serializer):
serializer.save(user=self.request.user)
def perform_update(self, serializer):
serializer.save(user=self.request.user)
串行:
class ExampleSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
class Meta:
model = ExampleModel
现在,我不断收到错误说:{"user":["This field is required."]}
,之前并非如此。在具有相同基本问题的稍微不同的示例中,即使我没有按要求设置用户,我也会收到断言错误May not set both 'read_only' and 'required'
。
无论是否在序列化程序中为用户属性添加required=False
,或者我将用户添加到序列化程序元素中的排除字段,我都会收到相同的错误。
当我使用方便的新系列打印机时,我看到:
class Meta:
validators = [UniqueTogetherValidator(queryset=ExampleModel.objects.all(), fields=('user', 'some_attr', 'other_attr'))]
根据模型的unique_together自动添加。如果我明确覆盖此内容并且未包含“用户”#39;在UniqueTogetherValidator
的字段中,一切都像以前一样。
这是3.0更新的预期后果吗?在我看来,在request.user
/ perform_create
中添加perform_update
是非常标准的DRF过程,如教程中所示。我意识到没有新的验证只是意味着在数据库级别失败,而新的验证可能会提供更好的错误消息,但
除了覆盖每个序列化程序的验证之外,还有其他解决方案吗?
提前感谢您的帮助!
答案 0 :(得分:7)
这是a known issue,我们正在Django REST Framework中进行寻址。截至目前,documentation about UniqueTogtherValidator中有一条说明
的说明注意:
UniqueTogetherValidation
类总是强加一个隐式约束,它所应用的所有字段始终被视为必需。具有default
值的字段是一个例外,因为即使从用户输入中省略它们也总是提供值。
这解释了为什么您看到错误,因为该字段是必需的,即使您明确设置read_only=True
。您可能需要查看CurrentUserDefault
class,这可能符合您的需求,同时避免UniqueTogetherValidator
的问题。
class ExampleSerializer(serializers.ModelSerializer):
user = UserSerializer(
read_only=True
default=serializers.CurrentUserDefault()
)
class Meta:
model = ExampleModel
此 应该与您的perform_create
和perform_update
挂钩做同样的事情。