Переопределение is_valid во вложенном сериализаторе, чтобы иметь возможность обрабатывать дочернюю модель с той же информацией во время update()
Я пытаюсь сделать так, чтобы мой вложенный сериализатор мог обрабатывать обновления, когда я обновляю только родительскую модель. Действие по умолчанию в drf таково, что сериализатор не может определить, пытается ли дочерняя модель обновить или создать, есть решение, где вы просто отключаете валидацию, но я не думаю, что это идеально для базы данных и iots импликации.
Я бился над этой темой около 2 дней и думаю, что идеальный подход к этому - переопределить метод is_valid, чтобы иметь возможность просто вернуть объект.
Идея от :
Django REST Framework ModelSerializer get_or_create функциональность
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
class MyModelSerializer(serializers.ModelSerializer):
def is_valid(self, raise_exception=False):
if hasattr(self, 'initial_data'):
# If we are instantiating with data={something}
try:
# Try to get the object in question
obj = Security.objects.get(**self.initial_data)
except (ObjectDoesNotExist, MultipleObjectsReturned):
# Except not finding the object or the data being ambiguous
# for defining it. Then validate the data as usual
return super().is_valid(raise_exception)
else:
# If the object is found add it to the serializer. Then
# validate the data as usual
self.instance = obj
return super().is_valid(raise_exception)
else:
# If the Serializer was instantiated with just an object, and no
# data={something} proceed as usual
return super().is_valid(raise_exception)
class Meta:
model = models.MyModel
Проблема в том, что при попытке имплантации я получаю ошибку:
Поле 'id' ожидало число, но получило [{'id': 18, 'title': 'aDDD', 'body': 'aDDD', 'slug': 'aDDDbabe', 'author': 1, 'вопрос': 25}].
obj = Question.objects.get(**self.initial_data)
Этот код запускает его, однако, когда я
obj = Question.answers.get(**self.initial_data)
У объекта 'ReverseManyToOneDescriptor' нет атрибута 'get' .
Поскольку мой сериализатор является вложенным, мне придется найти другой способ заставить его работать. Посоветуйте, где я могу это исправить? :(
serializers.py
views.py
from django.shortcuts import render
from .models import Question, Answer
from django.conf import settings
from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
from .serializers import QuestionSerializer
#from .permissions import UpdateOwnPrice
from rest_framework.permissions import IsAdminUser
class QuestionViewSet(viewsets.ModelViewSet):
"""CRUD """
serializer_class = QuestionSerializer
queryset = Question.objects.all()
authentication_classes = (TokenAuthentication,)
#permission_classes = (UpdateOwnPrice,)
lookup_field = 'slug'
extra_kwargs = {'slug': {'validators': []},}
models.py
from django.db import models
from django.conf import settings
from django.db.models import Q
from django.utils import timezone
from django.urls import reverse
class Category(models.Model):
name= models.CharField(max_length=100)
def __str__(self):
return self.name
class Question(models.Model):
title= models.CharField(max_length= 100)
body= models.TextField()
slug= models.SlugField(unique= True)
date_posted= models.DateTimeField(default=timezone.now)
author= models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE, related_name = 'questions')
category= models.ForeignKey(Category, on_delete= models.CASCADE, related_name = 'questions')
#objects= QnAManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('home')
class Answer(models.Model):
title= models.CharField(max_length= 100)
body= models.TextField()
slug= models.SlugField(unique= True)
date_posted= models.DateTimeField(default=timezone.now)
author= models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE, related_name = 'answers')
question= models.ForeignKey(Question, on_delete= models.CASCADE, related_name = 'answers')
#objects= QnAManager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('home')