Как создать экземпляр модели Django, который содержит необходимый OneToOneField с сериализаторами DRF - PullRequest
0 голосов
/ 15 февраля 2019

Вопрос

Допустим, у меня есть модель, которая содержит OneToOneField примерно так:

models.py

class Event(models.Model)
    # some basic fields...

class EventDetail(models.Model):
    event = models.OneToOneField(Event, on_delete=models.CASCADE,
                          related_name='event_detail')
    # other basic fields, all with default values...

Как правильно реализовать запрос POST, который намеревается создать новый Event в базе данных, который автоматически создает связанный с ним EventDetail по умолчанию, если в заголовке запроса указано None, с использованием сериализаторов Django Rest Framework?

Моя попытка

test.py

class EventTestCase(APITestCase):
    def test_post(self):
        # Need to provide an id, or else an error occurs about the OneToOneField
        event = Event(id=1)
        serializer = serializers.EventSerializer(event)
        res = self.api_client.post('/event/', serializer.data)

views.py

def post(self, request, format=None):
    serializer = EventSerializer(
        data=request.data)
    # ***This always returns false!***
    if serializer.is_valid():
        try:
            instance = serializer.save()
        except ValueError:
            return Response(status=status.HTTP_400_BAD_REQUEST)

serializers.py

class EventSerializer(serializers.ModelSerializer):
    serialization_title = "Event"
    event_detail = EventDetailSerializer()

    class Meta:
        model = Event
        exclude = ('id',)
        error_status_codes = {
            HTTP_400_BAD_REQUEST: 'Bad Request'
        }

class EventDetailSerializer(serializers.ModelSerializer):
    serialization_title = "Event Detail"

    class Meta:
        model = models.EventDetail
        exclude = ('id',)
        error_status_codes = {
            HTTP_400_BAD_REQUEST: 'Bad Request'
        }

Как отмечено в комментарии выше, serializer.is_valid() всегда возвращает false с ошибкой:

{'event_detail': [u'Это поле не может быть пустым. ']}

Я понимаю, что это вызывает недовольство, поскольку необходимо создать как EventDetail, так и Event, чтобы отношения OneToOne былидобавил, но как вы справляетесь с этим с помощью Serializer, когда OneToOneField требуется, но еще не предоставлен клиентом?

Спасибо за yнаша помощь.

Отказ от ответственности: я использую Django 1.11

1 Ответ

0 голосов
/ 15 февраля 2019

Вы можете объявить EventDetailSerializer с помощью read_only=True или required=False, а затем обработать создание EventDetail различными способами, например: у вас может быть сигнал post_save, который прослушивает Eventclass - после создания нового объекта Event вы можете создать исходный объект EventDetail или выполнить его после serializer.save() в определении post или даже в методе createваш EventSerializer.

edit: пример того, как вы могли бы выполнить создание, используя EventDetailSerializer и переопределив метод create вашего EventSerializer.

def create(self, validated_data):
    detail = self.initial_data.get('event_detail')
    instance = super().create(validated_data)
    if detail:
        serializer = EventDetailSerializer(data=detail)
        serializer.is_valid(raise_exception=True)
        serializer.save(event=instance)
    return instance
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...