2015-08-10 4 views
1

Я хотел создать уникальное поле электронной почты для модели пользователя django по умолчанию. Поэтому я сделал это unique_together=[('email',)]. Теперь в сериализаторе я хочу, чтобы это поле read_only. Но Джанго Rest Framework 3.0 Docs говорит:Поле read_only в сериализаторе отдыха django with unique_together contraint

Существует особый случай, когда поле только для чтения является частью unique_together ограничения на уровне модели. В этом случае поле требуется классом сериализатора для проверки ограничения , но также не может быть доступно для редактирования пользователем.

Правильный способ справиться с этим - указать поле явно на сериализаторе, предоставляя как аргументы read_only = True, так и default = ... .

Одним из примеров этого является только для чтения отношения к текущим аутентифицированному пользователю, который является unique_together с другим идентификатором. В этом случае вы бы объявить поле пользователя следующим образом:

пользователя = serializers.PrimaryKeyRelatedField (read_only = True, по умолчанию = serializers.CurrentUserDefault())

serializers.CurrentUserDefault() представляет собой текущий пользователь. Я хочу установить по умолчанию в качестве электронной почты пользователя. Не соответствует serializers.CurrentUserDefault(), эквивалентному request.user. serializers.CurrentUserDefault().email дает ошибку 'CurrentUserDefault' object has no attribute 'email' Как установить email по умолчанию в качестве электронного адреса пользователя?

+0

Можете ли вы решить эту проблему? или Вы находите любое другое решение? –

ответ

2

Это то, что документация CurrentUserDefault говорит:

класс по умолчанию, которые могут быть использованы для представления текущего пользователя. В , чтобы использовать это, 'request' должен быть предоставлен как часть контекстного словаря при создании экземпляра сериализатора.

Вы можете сделать это, или вы можете предоставить электронный идентификатор, переданный в context data в вашем views. Переопределить функцию get_serializer_context

def get_serializer_context(self): 
    context = super(YourClass, self).get_serializer_context() 
    context['email'] = request.user.email 

    return context 

в вашем views. Ваш view должен быть продлен с GenericAPIView на определенном уровне наследования. Теперь в вашем serializer, переопределите __init__ и получите данные электронной почты.

def __init__(self, instance = None, data = serializers.empty, *args, **kwargs): 
    self.email = kwargs['context']['email'] 

Теперь вы можете использовать это в своем сериализаторе.

+0

'Ваше мнение должно быть расширено от GenericAPIView' Почему? , Я использую функции, основанные на представлении и передающем контексте, например 'serializer = UserProfileSerializer (request.user, data = request.data, context = {'request': request})' –

+0

Да, что бы это сделать и получить ваш контекст в kwargs –

+0

Пытался использовать это в сериализаторе 'def __init __ (self, instance = None, data = serializers.empty, * args, ** kwargs): self.email = kwargs ['context'] ['request']. User.email . Я получаю Не могу позвонить '.is_valid() ', поскольку при создании экземпляра serializer не передавался аргумент ключевого слова' data = '. –

Смежные вопросы