Я делаю обновление до DRF3.1.1 с версии 2.4. Я использовал собственный сериализатор для создания экземпляра объекта, а не модели.
В 2.4 это было достаточно просто сделать, потому что в сериализаторе я бы создал объект в restore_object()
. В представлении я бы назвал serializer.is_valid()
, а затем вытащил экземпляр объекта из сериализатора с помощью serializer.object
. Тогда я мог делать все, что захочу.
С изменениями 3.x сложнее получить экземпляр из объекта, потому что методы создания и обновления должны выполнять сохранение, а "serializer.object" больше не доступен.
В качестве примера я использовал это для своего объекта "UserRegistration". Это не модель, потому что это удобный объект, который сервер анализирует и хранит данные в ряде других объектов/таблиц db.
class UserRegistration(object):
def __init__(self, full_name, stage_name, password="", email="", locale="en_US"):
self.full_name = full_name
self.password = password
self.locale = locale
self.email = email
self.stage_name = stage_name
Здесь связанный сериализатор DRF-2.4:
class UserRegistrationSerializer(serializers.Serializer):
full_name = serializers.CharField(max_length=128, required=False)
stage_name = serializers.CharField(max_length=128)
password = serializers.CharField(max_length=128, required=False)
locale = serializers.CharField(max_length=10, required=False)
# use CharField instead of EmailField for email. We do our own validation later to make for a better error msg.
email = serializers.CharField(max_length=254, required=False)
def restore_object(self, attrs, instance=None):
if instance is not None:
instance.full_name = attrs.get('full_name', instance.full_name)
instance.password = attrs.get('password', instance.password)
instance.locale = attrs.get('locale', instance.locale)
instance.email = attrs.get('email', instance.email)
instance.stage_name = attrs.get('stage_name', instance.stage_name)
return instance
return UserRegistration(**attrs)
Тогда, на мой взгляд, я делаю что-то вроде этого:
class UserRegistration(APIView):
throttle_classes = ()
serializer_class = UserRegistrationSerializer
def post(self, request, format=None):
event_type = "user_registration"
serializer = UserRegistrationSerializer(data=request.DATA, context={'request': request})
try:
if serializer.is_valid():
user_registration = serializer.object
# save user_registration pieces in various places...
Однако в DRF3 я serializer.object
исчез. Документы говорят, что делать "валидацию" с помощью serializer.validated_data
, но это только хэш, а не реальный объект. Есть ли способ получить объект?
Все это кажется более влюбленным в объекты БД, которые в данном конкретном случае именно то, чего я пытаюсь избежать.
Я просто пропустил новую концепцию DRF3?