Как правильно сохранить 200 объектов в базе данных, используя django-rest-framework? - PullRequest
0 голосов
/ 01 июня 2019

У меня есть проблема, которую нужно решить на следующей неделе в проекте.У меня есть модель с 3 полями, 2 из которых являются внешним ключом для других моделей, а другое поле является простым строковым полем.Во внешнем интерфейсе я собираюсь представить пользователю только флажок и поле наблюдения, строковое поле, которое может быть пустым или нулевым.Будет список флажков, около 200. Каждый из них будет объектом в базе данных.Я не хочу делать запрос на публикацию для каждого из них, из-за чего пользовательский интерфейс будет очень плохим, 200 полей уже очень плохие, но в данном случае это необходимо.

Так что мне нужны предложения, кодПример о лучшем подходе для достижения этой цели.Вот модель.

class Person(models.Model):
    observation = models.TextField(blank=True, null=True)
    country = models.ForeignKey(Country, on_delete=models.PROTECT)
    user = models.ForeignKey(User, on_delete=models.PROTECT)

У меня есть сериализатор и ModelViewSet, работающий на него с одним запросом, работает запрос POST для 1 объекта.

class PersonSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

Я бы хотел, чтобы клиент отправил на сервер большой список / массив / объект, не уверен, и сервер получит все эти данные в одном запросе POST и запуститпроцесс, чтобы сохранить его в базе данных.Я подумал, что если бы лучший подход заключался в том, чтобы перебрать эти данные и вызвать сериализатор для каждого в представлении, или если бы я реализовал сериализатор нового типа, чтобы сделать его.
Я прочитал эти два вопроса question1 и question2 об этом, и это было действительно полезно, но у меня все еще есть сомнения.И еще одна проблема: если возникает ошибка, например, если сервер отключается в середине процесса, соединение прерывается, что-то происходит, тогда мои данные будут сохранены или будут прерваны в середине, я спрашиваюпотому что я не могу разделить эти данные, мне нужно гарантировать, что все 200 полей будут сохранены или 0 полей будут сохранены.

1 Ответ

2 голосов
/ 01 июня 2019

Вы можете передать список данных в сериализатор и проверить все сразу, передав множество аргументов в сериализатор

example_data = [
 {'country': 1, 'user': 1, 'observation': ''},
 {'country': 1, 'user': 2, 'observation': ''},
 {'country': 2, 'user': 1, 'observation': ''},
 {'country': 2, 'user': 2, 'observation': ''},
]

serializer = PersonSerializer(data=example_data, many=True)

if serializer.is_valid():
    serializer.save()

Этот сериализатор будет действителен тогда и только тогда, когда все экземпляры данных действительны, и будет создавать объект для каждого элемента данных.

Если вас беспокоит сбой на уровне базы данных, вы всегда можете использовать атомарную транзакцию в методе создания сериализатора.

from django.db import transaction


class PersonSerializer(serializer.ModelSerializer):
    ...

    def create(self, validated_data):
        with transaction.atomic():
            return super().create(validated_data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...