0

My code generates Pandas dataframes. They are big. I save them as files. For this, I have created this Model:

models.py:

class TargetFiles(models.Model):
    owner = models.CharField(max_length=25)
    csv_file = models.FileField(blank=True, upload_to='target')
    file_name = models.CharField(max_length=255)

settings.py:

...
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT =  os.path.join(BASE_DIR, 'media')

mycode.py:

file_content = df.to_csv(index=False, encoding='utf-8')
csvname = 'target1.csv'
csf = ContentFile(file_content, csvname)
TargetFiles.objects.create(owner=self.user, csv_file=csf, file_name=csvname)

urls.py (project):

from django.urls import include, path
from django.contrib import admin

urlpatterns = [
    path('dataapp/', include('dataapp.urls')),
]

urls.py (dataapp):

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='dataapp'),
    path('welcome/', views.welcome_dataapp, name='welcome_dataapp'),
    path('download/<str:file_name>', views.download, name='download'),
]

I don't know if this is the best approach for the problem. This documentation made me skeptical. The thing is that my code is generating the file properly, and saving it in the MEDIA_ROOT directory. But when I go to admin view and click on TargetFiles object, the link to the file returns this error:

The current path, media/target/target1.csv, didn't match any of these.

Since I am not an Django expert, I think I am setting something wrong. Maybe in settings.py or in urls.py (in this file I didn't write any reference to media, maybe this is where the error lives).

I have already read these posts: Django - how to create a file and save it to a model's FileField? , Django: generate a CSV file and store it into FileField and this assign resulting csv file to django model. But I was not able to make the admin link point to the MEDIA_ROOT file.

Does anyone have ideas?

Thanks in advance.

O Pardal
  • 647
  • 4
  • 21

1 Answers1

0

Django does not serve the files stored in the MEDIA_ROOT. You can enable this during development by adding the following to your root url config:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

https://docs.djangoproject.com/en/3.0/howto/static-files/#serving-files-uploaded-by-a-user-during-development

It's recommended to let file serving be handled by some other server (apache or nginx) whe deploying to a production server.

jaap3
  • 2,696
  • 19
  • 34
  • Thank you. I tried this solution, but it keeps me returning the same error message. Do you have any clue what it's possibly happening? – O Pardal Feb 03 '20 at 14:56
  • 1
    Did you reload Django after changing `urls.py` and is `DEBUG` set to `True` in `settings.py`? Also, make sure you've added this to the root `urls.py` (the project one) not the one in `dataapp`. – jaap3 Feb 03 '20 at 14:59
  • Yes, I have reloaded and set DEBUG=True. – O Pardal Feb 03 '20 at 15:02
  • 1
    Could you post the full error text of the `The current path, media/target/target1.csv, didn't match any of these.` message? Django usually lists the available url patterns, so there might be a clue there. – jaap3 Feb 03 '20 at 15:09
  • It worked. I had changed the wrong urls.py. Sorry and thanks again. – O Pardal Feb 03 '20 at 15:11