Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializer not writing individual object from queryset

I am using a ModelForm to capture some data for a model and, while I want this data saved to a db, I also want to export it to an XML file for transformation/use in an external system.

Please see below for an example:

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})

The object is serializing appropriately in the HttpResponse (ie I can see an acceptable XML output), but there is no output in the XML file itself. If I remove the QuerySet filter (i.e. call .all()), then the XML file will correctly have all objects related to the Warranty model. It seems strange that the behaviour is fine in one circumstance in not theother, so I can't trouble shoot any further.

like image 567
Edward Avatar asked Feb 13 '20 05:02

Edward


People also ask

How do I pass Queryset to serializer?

How do I pass Queryset to serializer? To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

How serializer works in Django?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

What does serializer data return in Django?

Serialization transforms data into a format that can be stored or transmitted and then reconstructs it for use. DRF has the best-known serializers. Serialization is the process of transforming data into a format that can be stored or transmitted and then reconstructing it.

What is depth in Django serializer?

DRF allows you to expose a REST framework based on your django data models with very little code needed. To get a basic REST API that supports Create-Read-Update-Delete operations on your data you have to do two things: You specify a serializer that tells drf how to go from your model to a JSON representation.


1 Answers

The issue is that you're trying to serialize the objects before they are actually saved to the database - so the queryset passed to the serializer will not contain this new item. Change the order around:

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

Also note that your current logic write a new serialization to the file inside your for loop - which I am not sure is what you want. You could instead serialize everything at once like so:

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)
like image 74
solarissmoke Avatar answered Oct 16 '22 05:10

solarissmoke