Сериализатор не пишет отдельный объект из набора запросов - PullRequest
6 голосов
/ 13 февраля 2020

Я использую ModelForm для сбора некоторых данных для модели и, хотя я хочу сохранить эти данные в БД, я также хочу экспортировать их в файл XML для преобразования / использования во внешней системе.

См. Пример ниже:

def warranty(request):
    WarrantyFormSet = modelformset_factory(Warranty, form=WarrantyForm)
    if request.method == 'POST':
        formset = WarrantyFormSet(request.POST, request.FILES)
        if formset.is_valid():
            new = formset.save(commit=False)
            out = open("file.xml", "w")
            XMLSerializer = serializers.get_serializer("xml")
            xml_serializer = XMLSerializer()

            for n in new:
                xml_serializer.serialize(Warranty.objects.all(), stream=out)
                #.filter(id = n.id)
                n.save()

            return HttpResponse(xml_serializer.serialize(Warranty.objects.filter(id = n.id)))
    else:
        formset = WarrantyFormSet(queryset = Warranty.objects.none())
    return render(request,'warranty.html', {'formset': formset})

Объект соответствующим образом сериализуется в HttpResponse (ie Я вижу приемлемый вывод XML), но нет вывода в самом файле XML. Если я удалю фильтр QuerySet (т.е. вызову .all ()), тогда в файле XML будут все объекты, связанные с моделью гарантии. Кажется странным, что в одних обстоятельствах все в порядке, и я не могу больше стрелять.

1 Ответ

2 голосов
/ 15 февраля 2020

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

for n in new:
    n.save()
    xml_serializer.serialize(Warranty.objects.filter(id=n.id), stream=out)

Также обратите внимание, что ваши текущие логи c записывают новую сериализацию в файл внутри вашего для l oop - что я не уверен, что вы хотите. Вместо этого вы можете сериализовать все сразу так:

if request.method == 'POST':
    formset = WarrantyFormSet(request.POST, request.FILES)
    if formset.is_valid():
        new_items = formset.save()  # commit = True since you don't need to change anything before saving
        new_item_ids = [n.id for n in new_items]
        with open("file.xml", "w") as out:
            XMLSerializer = serializers.get_serializer("xml")
            xml_serializer = XMLSerializer()
            xml_serializer.serialize(
                Warranty.objects.filter(id__in=new_item_ids), stream=out)
...