DRF 3.0: UniqueTogetherValidator с полем только для чтения
в процессе обновления до Django Rest Framework 3.0 от 2.4.4, и я хочу иметь поле пользователя только для чтения, но это не удается, потому что "пользователь" требуется 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')
Viewset:
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
для атрибута user в сериализаторе или если я добавляю user в исключенные поля в meta сериализатора.
когда я использую удобный новый сериализатор печати, я вижу:
class Meta:
validators = [UniqueTogetherValidator(queryset=ExampleModel.objects.all(), fields=('user', 'some_attr', 'other_attr'))]
который автоматически добавляется на основе unique_together модели. если я явно перепишите это и не включайте "user" в поля для UniqueTogetherValidator
тогда все работает по-прежнему.
является ли это предполагаемым следствием обновления 3.0? Мне кажется, что добавление request.user
на perform_create
/ perform_update
очень стандартная процедура DRF, как показано в учебнике. Я понимаю, что отсутствие новой проверки просто означает сбой на уровне БД, а новая проверка, вероятно, дает лучшие сообщения об ошибках, но
есть решение, отличное от переопределения проверки для каждого сериализатора, где это проблема?
заранее спасибо за любую помощь!
1 ответов
это известная проблема что мы находимся в процессе решения в рамках Django REST. На данный момент в документация по UniqueTogtherValidator что говорит
Примечание: на
UniqueTogetherValidation
класс всегда накладывает неявное ограничение, что все поля, к которым он применяется, всегда обрабатываются по мере необходимости. Поляdefault
значения являются исключением из этого, поскольку они всегда предоставляют значение даже если опущено из пользовательского ввода.
это объясняет, почему вы видите ошибку, потому что поле требуется, даже если вы явно настройки read_only=True
. Вы можете посмотреть в CurrentUserDefault
класс, который может удовлетворить ваши потребности, избегая при этом проблемы с UniqueTogetherValidator
.
class ExampleSerializer(serializers.ModelSerializer):
user = UserSerializer(
read_only=True
default=serializers.CurrentUserDefault()
)
class Meta:
model = ExampleModel
этой должны сделайте то же самое, что и ваш perform_create
и perform_update
крючки.