Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Django REST Framework - подставить в значение поля id текущего пользователя [RSS Feed]

#1 Янв. 22, 2015 12:39:39

dun
От: Липецк
Зарегистрирован: 2015-01-16
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

Здравствуйте!

Не могу написать сериализатор для модели, который будет подставлять в значение поля id текущего пользователя в момент создания записи, в остальное же время возвращающий только id и ФИО пользователя.
Модель:

from django.models import models
from django.conf import settings
class NewsItem(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)

Сериализаторы:
class NewsReadSerializer(serializers.ModelSerializer):
    author = UserSerializer()
    class Meta:
        model = NewsItem
class NewsWriteSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewsItem

В api.py нужный сериализатор выбирается путём анализа параметров объекта request:

class NewsList(ListCreateAPIView):
    queryset = NewsItem.objects.sorted('-pub_date')
    def get_serializer_class(self, *args, **kwargs):
        if self.request.method == 'GET':
            return NewsReadSerializer
        return NewsWriteSerializer
    class Meta:
        model = NewsModel

При сохранении новой модели класса NewsItem получаю ошибку 400 Bad Request с сообщением о том, что поле author обязательно для заполнения. Пробовал определять метод validate_author для сериализатора NewsWriteSerializer, но это не дало результата.
Что делать?

Отредактировано dun (Янв. 22, 2015 13:34:40)

Офлайн

#2 Янв. 22, 2015 13:29:48

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

class NewsWriteSerializer(models.Model)
У вас тут опечатка. Должен быть class NewsWriteSerializer(serializers.ModelSerializer)
А так, да - нужно определить метод validate_author.

Отредактировано GreyZmeem (Янв. 22, 2015 13:30:01)

Офлайн

#3 Янв. 22, 2015 13:37:28

dun
От: Липецк
Зарегистрирован: 2015-01-16
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

GreyZmeem
Поправил опечатку. Как правильно описать validate_author?
У меня сейчас вот так и не работает:
class NewsWriteSerializer(serializers.ModelSerializer):
    
    def validate_author(self):
        return self.request.user.id
    
    class Meta:
        model = NewsModel 

Офлайн

#4 Янв. 22, 2015 14:44:38

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

Для DRF < 3

def validate_user(self, attrs, source):
        attrs.update({'user': self.context['request'].user})
        return attrs
Для DRF >= 3 (не проверял)
def validate_user(self, value):
        return self.context['request'].user

Также для обоих версий надо в serializer переопределить поле user и поставить required=False, иначе DRF вообще не вызовет validate для этого поля.
user = serializers.PrimaryKeyRelatedField(source='user', required=False)

Также добавьте в свой View permission class который проверяет авторизацию (чтобы не было 500 ошибки при сохранении)
from rest_framework import permissions
 
class NewsList(class NewsList(ListCreateAPIView):
        permission_classes = [permissions.IsAuthenticated]

Отредактировано GreyZmeem (Янв. 22, 2015 14:48:11)

Офлайн

#5 Янв. 22, 2015 15:28:12

dun
От: Липецк
Зарегистрирован: 2015-01-16
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

Поправил сериализатор, который использую для записи:

class NewsWriteSerializer(serializers.ModelSerializer):
    
    author = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), required=False)
    # В DRF 3 требуется указывать queryset для PrimaryKeyRelatedField, source уже не катит
    
    def validate_author(self, value):
        return self.context['request'].user
       
    class Meta:
        model = NewsModel      
        fields = ('title', 'announce', 'full_text', 'author') 

Теперь хотя бы другая ошибка - news.author_id may not be NULL
Кстати, вставил возбуждение исключения в методе validate_author() и не увидел его. Есть подозрение, что этот метод вовсе не вызывается сейчас.

Отредактировано dun (Янв. 22, 2015 15:28:53)

Офлайн

#6 Янв. 23, 2015 00:02:04

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

Что-то они сильно заморочились с проверками в 3
Поколупался в исходниках. Вобщем должно быть утсановлены allow_null & default.
Иначе в Field.validate_empty_values() будет вызван метод get_default() который сделает raise SkipField и никакие валидаторы для этого поля не запустяться.

class TestModelSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(
        queryset=User.objects.all(),
        allow_null=True,
        default=None
    )
 
    def validate_user(self, value):
        return self.context['request'].user
 
    class Meta:
        model = models.TestModel

Офлайн

#7 Янв. 23, 2015 07:23:06

dun
От: Липецк
Зарегистрирован: 2015-01-16
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

Django REST Framework - подставить в значение поля id текущего пользователя

Спасибо большое за помощь! Именно так, как Вы написали, всё работает, как положено.

Офлайн

  • Начало
  • » Django
  • » Django REST Framework - подставить в значение поля id текущего пользователя[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version