Search code examples
djangofiledjango-rest-frameworkdirectorydirectory-structure

Problem in creating folder and file after upload in Django


I'm creating a source code evaluater platform using React and Django. Basically an user is going to upload a source file of his choice, my frontend sends the file to backend, which is working fine, and my backend has to create a copy of the file in a specific folder structure, because the code evaluater (different application) is set to access this structure searching for new files.

The folder structure is basically like this: I've a first folder name Delivereds, inside it I've many folders named by the user id, inside each of these folders I've many folders named by the submission id.

To simplify this problem solving, let's deal with this ignoring user id, let's just focus on folder adress like this: "/Delivereds/Question1/code.c++".

My problem is that when I try to create a folder, it doesn't work. I'm pretty much a beginner in Django, so I don't really know if I need to set some configs in the main settings file. The solutions that I found in my searches are really simple and didn't work in my case.

My current code is like this:

elif request.method == 'POST':
        if request.FILES.get('file'):
            file = request.FILES['file']
            parent_dir = '..\Delivereds\Question1'
             
            path = os.path.join(parent_dir, file.name)

            try:
                if not os.path.exists(path):
                    print('hit')
                    os.mkdir(path)
                else:
                    print('no hit')
                
            except Exception as error:
                print(error)
            
            try:
                with open(path, 'wb+') as destiny:
                    for chunk in file.chunks():
                        destiny.write(chunk)
                        print(chunk)
            except Exception as error:
                print(error)

Below print(chunk), there is the serializer and the return stuff. I've tried different variations of this code already, like creating only the folder with os.mkdir(path) and using something like with open(path + file.name, 'wb+') as destiny.

This file is the view.py of an app called tasks_delivered. The idea is to create the Delivereds folder in the root of the Django application and store all the submissions there (suggestions on how to handle this more efficiently are welcome).

I use "hit" and "no hit" for debugging.

Both of the try blocks are returning errors, the output is this:

hit
[WinError 3] [WinError 3] The system cannot find the path specified: '..\\Delivereds\\Question1\\test.cpp'
[Errno 2] No such file or directory: '..\\Delivereds\\Question1\\test.cpp'

I think one relevant piece of information is that my application is also using images, so I had to change some settings related to static files in the main settings.py and urls.py.

settings.py:

STATIC_URL = 'static/'
MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

CKEDITOR_UPLOAD_PATH = "media/images"
CKEDITOR_CONFIGS = {
    'default': {
        'toolbar': 'Custom',
        'toolbar_Custom': [
            ['Bold', 'Italic', 'Underline'],
            ['NumberedList', 'BulletedList'],
            ['Link', 'Unlink'],
            ['RemoveFormat'],
        ],
        'width': '100%',
    },
}

urls.py:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('token/', TokenObtainPairView.as_view()),
    path('token/refresh/', TokenRefreshView.as_view()),
    path('api-auth/', include('rest_framework.urls')),
    path('', include('user.urls')),
    path('', include('disciplines.urls')),
    path('', include('semesters.urls')),
    path('', include('tasks.urls')),
    path('', include('task_question.urls')),
    path('', include('tasks_delivered.urls')),
    path('', include('task_classgroups.urls')),
    path('', include('classgroup.urls')),
    path('', include('related_topic.urls')),
    path('', include('tags.urls')),
    path('', include('field_areas.urls')),
    path('', include('question_historic.urls')),
    path('', include('questions.urls')),
    path('', include('strategy_correction.urls')),
    path('', include('strategy_classgroup.urls')),
    path('', include('strategy_discipline.urls')),
    path('', include('strategy_question.urls')),
    path('', include('strategy_task.urls')),
    path('', include('help_tips.urls')),
    path('', include('tips.urls')),
    path('', include('admin_type.urls')),
    path('', include('summaries.urls')),
    path('ckeditor/', include('ckeditor_uploader.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

I'm not getting why I'm having trouble with specified paths, I thought the purpose of os.mkdir(path) was to create a folder in the specified path if it didn't already exist. Can someone please help me fix my code and understand the problem?


Solution

  • Instead of using this, os.mkdir(path)

    try, os.makedirs(path) it will create the parent directory if it doesn't exists. If the intermediate directories in the path do not exist, it will create them.