Django - Import Export - Upload multiple files
Asked Answered
J

2

1

Im using django import-export module and Im following this documentation:

https://simpleisbetterthancomplex.com/packages/2016/08/11/django-import-export.html#importing-data


I want to create an upload-page where the user can upload multiple files.

This is how far I got:


views.py

def upload_data(request):
    if request.method == 'POST':
        wo_resource = WorkordersResource()
        pl_resource = PlantResource()
        se_resource = SeriesResource()
        re_resource = ResourcesResource()
        rd_resource = ResourceDemandsResource()
        dataset = Dataset()
        wo_data = request.FILES.get('workorders_key', None)
        pl_data = request.FILES.get('plants_key', None)
        se_data = request.FILES.get('series_key', None)
        re_data = request.FILES.get('resources_key', None)
        rd_data = request.FILES.get('resourcedemands_key', None)
        wo_imported_data = dataset.load(wo_data.read())
        pl_imported_data = dataset.load(pl_data.read())
        se_imported_data = dataset.load(se_data.read())
        re_imported_data = dataset.load(re_data.read())
        rd_imported_data = dataset.load(rd_data.read())
        wo_result = wo_resource.import_data(dataset, dry_run=True)
        pl_result = pl_resource.import_data(dataset, dry_run=True)
        se_result = se_resource.import_data(dataset, dry_run=True)
        re_result = re_resource.import_data(dataset, dry_run=True)
        rd_result = rd_resource.import_data(dataset, dry_run=True)
        if not wo_result.has_errors():
            wo_resource.import_data(dataset, dry_run=False)  
        elif not pl_result.has_errors():
            pl_resource.import_data(dataset, dry_run=False)  
        elif not se_result.has_errors():
            se_resource.import_data(dataset, dry_run=False)  
        elif not re_result.has_errors():
            re_resource.import_data(dataset, dry_run=False) 
        elif not rd_result.has_errors():
            rd_resource.import_data(dataset, dry_run=False) 
        else:
            print(result)
    return render(request,'import.html')

import.html

 <form class="importform" method="post" enctype="multipart/form-data"> {% csrf_token %}
        <div class="formlabel">
        <label class="uploadlabel">Workorders</label>
        <input class="uploadform" type="file" name="workorders_key" placeholder="Workorders">                
        </div>
        <div class="formlabel">
            <label class="uploadlabel">Plants</label>
            <input class="uploadform"  type="file" name="plants_key" placeholder="Plants">
        </div>
        <div class="formlabel">
        <label class="uploadlabel">Series</label>
        <input class="uploadform"  type="file" name="series_key" placeholder="Series">                
        </div>
        <div class="formlabel">
        <label class="uploadlabel">Resources</label>
        <input class="uploadform"  type="file" name="resources_key" placeholder="Resources">
        </div>
        <div class="formlabel">
        <label class="uploadlabel">Resource Demands</label>
        <input class="uploadform"  type="file" name="resourcedemands_key" placeholder="Resource Demands">                
        </div>
        <button type="submit" class="btn btn-primary">Upload</button>
      </form>

The data from the first file gets imported, the data from the other files not.


Thank you

Juxtapose answered 15/1, 2020 at 13:35 Comment(5)
Depending on which form is submitted, you either get a 'myfile' or a 'mychart' as key for the file (request.FILES.get('myfile')). So depending on which one, you just instantiate the corresponding ModelResource.Convolve
I need to create a separate upload view for each form and associate the request.FILES['KEY'] to the corresponding key of the form, right?Juxtapose
No you can do it one view. Just an if ... else... clauseConvolve
I packed everything in one function, but this doesnt seem to be rightJuxtapose
You can’t access a key in a dictionary using subscripting if it’s not there. Use get() instead, it returns None if the key doesn’t exist. request.FILES.get('plants_key'). This is basic python. Or if you don’t want None but an empty file as default request.FILES.get('plants_key', File()).Convolve
S
0

There has been a dependency update that broke django-import-export. You just need to force tablib version to 0.14.0.

There's an issue on django-import-export github: #1064

Secern answered 15/1, 2020 at 14:54 Comment(0)
P
0

You need to check that your file uploads are not Null. request.FILES will return the key error if its contents are null.

You need to set a default value with request.FILES.get('file', <default>) where <default> is either another file or None.

For example in your code, if we take None as the default value, the lines:

wo_data = request.FILES['workorders_key']
pl_data = request.FILES['plants_key']
se_data = request.FILES['series_key']
re_data = request.FILES['resources_key']
rd_data = request.FILES['resourcedemands_key']

should become:

wo_data = request.FILES.get('workorders_key', None)
pl_data = request.FILES.get('plants_key', None)
se_data = request.FILES.get('series_key', None)
re_data = request.FILES.get('resources_key', None)
rd_data = request.FILES.get('resourcedemands_key', None)
Phalangeal answered 23/1, 2020 at 11:44 Comment(9)
Added an example of how it should be implemented in your code.Phalangeal
Now I get: 'NoneType' object has no attribute 'read' @ pl_imported_data = dataset.load(pl_data.read())Juxtapose
That's because your uploaded files are null. So it's trying to read None. You need to put in some error handling before you continue and correct your file upload. However the method of doing so that I mentioned is the safer way of doing that.Phalangeal
I used the method you proposed and I selected a file for each upload form, so I don't see why it should be emptyJuxtapose
Ive posted the formsJuxtapose
Sorry I can't be more help but I can't figure out why it's null. At least nothing I can see in your form is wrong.Phalangeal
Do you think it's because I am submitting only one file at a time using one form? What if I try to upload all files with one form, do you think that would help?Juxtapose
Yes I would say that is likely. As the view doesn't check if you're only uploading to one or two fields. It just tries to read everything.Phalangeal
@Pypax Just seen you unaccepted my answer. Did something go wrong with the solution I gave?Phalangeal

© 2022 - 2024 — McMap. All rights reserved.