Trying to write a script to upload files to a django project

I have a django 3.x project where I can upload multiple files and associated form data through the admin pages to a model called Document. However, I need to upload a large number of files, so I wrote a small python script to automate that process.

I am having one problem with the script. I can't seem to set the name of the file as it is set when uploaded through the admin page.

Here is the script...I had a few problems getting the csrf token working correctly, so there may be some redundant code for that.

import requests
# Set up the urls to login to the admin pages and access the correct add page
URL1='http://localhost:8000/admin/'
URL2='http://localhost:8000/admin/login/?next=/admin/'
URL3 = 'http://localhost:8090/admin/memorabilia/document/add/'
USER='admin'
PASSWORD='xxxxxxxxxxxxx'
client = requests.session()

# Retrieve the CSRF token first
client.get(URL1)  # sets the cookie
csrftoken = client.cookies['csrftoken']

print("csrftoken1=%s" % csrftoken)

login_data = dict(username=USER, password=PASSWORD, csrfmiddlewaretoken=csrftoken)
r = client.post(URL2, data=login_data, headers={"Referer": "foo"})   

r = client.get(URL3)

csrftoken = client.cookies['csrftoken']
print("csrftoken2=%s" % csrftoken)

cookies = dict(csrftoken= csrftoken)

headers = {'X-CSRFToken': csrftoken}

file_path = "/media/mark/ea00fd8e-4330-4d76-81d8-8fe7dde2cb95/2017/Memorable/20047/Still Images/Photos/20047_Phillips_Photo_052_002.jpg"

data = {
    "csrfmiddlewaretoken": csrftoken,
    "documentType_id": '1',
    "rotation" : '0',
    "TBD": '350',
    "Title": "A test title",
    "Period": "353",
    "Source Folder": '258',
    "Decade": "168",
    "Location": "352",
    "Photo Type": "354",
    }
       
file_data = None
with open(file_path ,'rb') as fr:
    file_data = fr.read()

# storage_file_name is the name of the FileField in the Document model.

#response_1 = requests.post(url=URL3, data=data, files={'storage_file_name': file_data,}, cookies=cookies)
response_2 = client.post(url=URL3, data=data, files={'storage_file_name': file_data, 'name': "20047_Phillips_Photo_052_002.jpg"}, cookies=cookies,)

When I upload using the admin page, the name of the file is "20047_Phillips_Photo_052_002.jpg", as it should be (i.e. storage_file_name.name = 20047_Phillips_Photo_052_002.jpg).

When I run the script using files={'storage_file_name': file_data,} (see response_1 at the bottom of the script), the files uploads correctly except that the name of the file is "storage_file_name" and not "20047_Phillips_Photo_052_002.jpg" (i.e. storage_file_name.name = "storage_file_name").

When I upload using files={'storage_file_name': file_data, 'name': "20047_Phillips_Photo_052_002.jpg"} the name of the file is still "storage_file_name" (i.e. storage_file_name.name = "storage_file_name").

I looked in the request.FILES object when uploading a file through the admin page, and the _name field for each object is the name of the file being uploaded. The documentation for the django File object says it has a field called name.

What am I missing to get my script to upload a file the same way as the admin page does? By that I mean, the name of the file is not "storage_file_name".

When I change the last response= line to

response = client.post(url=URL3, data=metadata, files= {'storage_file_name': open(file_path ,'rb'),}, cookies=cookies, headers=headers)

the file upload works and the file name is correctly displayed.

Back to Top