Forums

Upload folder defaulting to home directory

I have a Django project in a directory called 'planner'. I would like all uploaded csv files to be saved in 'planner/uploads' as I would like to keep the Django projects separated. Currently if I upload csv files they're automatically saved to '~/uploads' and I get an error saying that the file could not be found, but the outputted filename is correct.

As a workaround I'm testing to see if the app is in debug mode, and if it isn't then I'm adjusting the filename to load files in the '~/uploads' directory. What am I doing wrong? I have attached the offending code below:

    if request.method == 'POST':
        file_path = request.FILES.get('csv_upload')
        upload = Upload.objects.create(file=file_path)

        relative_path = upload.file.url
        base_url = str(settings.BASE_DIR)
        absolute_path = base_url + relative_path

        if settings.DEBUG:
            try:
                with open(absolute_path, 'r') as file:
                    for line in file:
                        fields = line.split(',')
                        loader = Loader.objects.get(name=fields[0])

                        Shift.objects.update_or_create(
                            loader = loader,
                            name = fields[1],
                            start = fields[2],
                            finish = fields[3]
                        )

                messages.success(request, 'Data imported successfully.')
            except Loader.DoesNotExist:
                messages.error(request, f'Loader \'{fields[0]}\' does not exist.')
            except Exception as e:
                messages.error(request, str(e))

        if not settings.DEBUG:
            try:
                with open('/'.join(['/home/<username>/', relative_path]), 'r') as file:
                    for line in file:
                        fields = line.split(',')
                        loader = Loader.objects.get(name=fields[0])

                        Shift.objects.update_or_create(
                            loader = loader,
                            name = fields[1],
                            start = fields[2],
                            finish = fields[3]
                        )

                messages.success(request, 'Data imported successfully.')
            except Loader.DoesNotExist:
                messages.error(request, f'Loader \'{fields[0]}\' does not exist.')
            except Exception as e:
                messages.error(request, str(e))

If you want files to be uploaded to a particular directory, then use the full path to that directory to save the files there.

Thank you glenn for the advice. I finally got round to updating the code. I ended up streamlining quite a bit and the finished code is below:

    if request.method == 'POST':
        upload_file = request.FILES.get('csv_upload')

        relative_path = self.file_name(upload_file)
        base_path = str(settings.BASE_DIR)
        absolute_path = os.path.join(base_path, relative_path)

        if not settings.DEBUG:
            absolute_path = os.path.join('/home/<user>/planner/uploads/', relative_path)

        try:
            with open(absolute_path, 'wb+') as destination:
                for chunk in upload_file.chunks():
                    destination.write(chunk)

            with open(absolute_path, 'r') as file:
                for line in file:
                    fields = line.strip().split(',')
                    loader = Loader.objects.get(name=fields[0])

                    Shift.objects.update_or_create(
                        loader=loader,
                        name=fields[1],
                        start=fields[2],
                        finish=fields[3]
                    )

            messages.success(request, 'Data imported successfully.')
        except Loader.DoesNotExist:
            messages.error(request, f'Loader \'{fields[0]}\' does not exist.')
        except Exception as e:
            messages.error(request, str(e))