Есть ли способ использовать bulk_create с наборами форм модели? - PullRequest
0 голосов
/ 21 мая 2019

В настоящее время я использую набор форм модели в своем проекте.

Проблема, которую я нахожу, заключается в том, что приложению, возможно, придется показывать более 50 форм на одной странице, поэтому при их сохранении с использованием метода .save() будет создано более 50 запросов (по одному запросу на каждую форму, которую я собираюсь сохранить).

Поскольку все формы имеют одинаковую структуру, было бы идеально иметь возможность сохранять их с помощью bulk_create таким образом, чтобы генерировался только один запрос, однако набор моделей не поддерживает bulk_create.

Можно ли как-то сохранить все ответы в формах одним запросом?

Единственное, о чем я могу подумать, это после проверки форм с помощью formset.is_valid(), восстановить request.POST и оттуда сохранить с помощью bulk_create.

Есть ли лучшая альтернатива?

1 Ответ

0 голосов
/ 21 мая 2019

Я думаю, вы очень близки к решению (но вы также можете использовать form.cleaned_data, а не QueryDict). Сейчас я покажу вам мою реализацию (которая использует метод bulk_create() Manager/QuerySet. Это поможет нам избежать большого количества попаданий на DB)

forms.py

class MyForm(forms.Form):
    ''' use same names for fields as you have in models.py '''
    name = forms.CharField()
    surname = forms.CharField()

models.py

class Person(models.Model):
        name = models.CharField(max_length=55)
        surname = models.CharField(max_length=55)

        class Meta:
            db_table = 'person'

views.py

from django.shortcuts import render
from django.http import JsonResponse
from django.forms import formset_factory
from django.db import connection
from .models import Person
from .forms import MyForm

N = 3 # number of forms
def index(request):
    FormSet = formset_factory(MyForm, extra=N)
    if request.method == 'POST':
        fs = FormSet(data=request.POST)
        if fs.is_valid():
            data_for_bulk = [Person(**field_dict) for field_dict in fs.cleaned_data] # this returns list and pass to bulk_create() method.
            Person.objects.bulk_create(data_for_bulk)
            # use connection.queries to make monitoring of sql queries during HTTP POST request.
            for query in connection.queries:
                print(query['sql'], '\n')
            return JsonResponse({'status_message': 'OK'})
    else:
        fs = FormSet()
    return render(request, 'test.html', {'form': fs})

Надеюсь, мое решение вам поможет. Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...