How to get the extension of a file in Django?

25,599

Solution 1

You could also use the clean() method from the form, which is used to validate it. Thus, you can reject files that are not mp3. Something like this:

class UploadSong(forms.Form):
    [...]

    def clean(self):
        cleaned_data = super(UploadSong, self).clean()
        file = cleaned_data.get('file')

        if file:
            filename = file.name
            print filename
            if filename.endswith('.mp3'):
                print 'File is a mp3'
            else:
                print 'File is NOT a mp3'
                raise forms.ValidationError("File is not a mp3. Please upload only mp3 files")

        return file

Solution 2

for get direct of request:

import os


extesion = os.path.splitext(str(request.FILES['file_field']))[1]

or get extesion in db - model.

import os

file = FileModel.objects.get(pk=1)  # select your object
file_path = file.db_column.path  # db_column how you save name of file.

extension = os.path.splitext(file_path)[1]

Solution 3

with import mimetypes, magic:

mimetypes.MimeTypes().types_map_inv[1][
    magic.from_buffer(form.cleaned_data['file'].read(), mime=True)
][0]

gives you the extension as '.pdf' for example

https://docs.djangoproject.com/en/dev/topics/forms/#processing-the-data-from-a-form
http://docs.python.org/2/library/mimetypes.html#mimetypes.MimeTypes.types_map_inv
https://github.com/ahupp/python-magic#usage

Solution 4

You mean this:

u_file = request.FILES['file']            
extension = u_file.split(".")[1].lower()

if(handle_uploaded_song(file)):
    path = '%s' % u_file
    ruta =  "http://example.com/static/canciones/%s" % path
    usuario = Usuario.objects.get(pk=request.session['persona'])
    song = Cancion(autor=usuario, cancion=ruta)
    song.save()
    return HttpResponse(content_type)

Solution 5

You can use request.FILES["file_field_name"].content_type

my_file = request.FILES["file_field_name"]
if my_file.content_type != 'text/csv':
    print("Your file must be a CSV type")

Share:
25,599
Marcos Aguayo
Author by

Marcos Aguayo

Fullstack developer

Updated on July 16, 2022

Comments

  • Marcos Aguayo
    Marcos Aguayo almost 2 years

    I'm building a web app in Django. I have a form that sends a file to views.py.

    Views:

    @login_required(login_url=login_url)
    def addCancion(request):
        if request.method == 'POST':
            form2 = UploadSong(request.POST, request.FILES)
            if form2.is_valid():
                if(handle_uploaded_song(request.FILES['file'])):
                    path = '%s' % (request.FILES['file'])
                    ruta =  "http://domain.com/static/canciones/%s" % path
                    usuario = Usuario.objects.get(pk=request.session['persona'])
                    song = Cancion(autor=usuario, cancion=ruta)
                    song.save()
                    return HttpResponse(ruta)
                else:
                    return HttpResponse("-3")
            else:
                return HttpResponse("-2")
        else:
            return HttpResponse("-1")   
    

    I'm trying to upload only the MP3 files, but I don't know how to make this filter. I tried a class named "ContentTypeRestrictedFileField(FileField):" and doesn't work.

    How can I get the file type in views.py?

    Thanks!

  • Aya
    Aya about 11 years
    ...or os.path.splitext(file)[1]
  • Marcos Aguayo
    Marcos Aguayo about 11 years
    I get this error: 'InMemoryUploadedFile' object has no attribute 'split'
  • Silas Ray
    Silas Ray about 11 years
    If all he's going to do is filter based upon the file extension, it's really just convenience functionality (someone could easily upload a file containing any arbitrary data with an MP3 file extension, or an MP3 without that file extension, for that matter), so he should probably be doing it client-side to reduce the request size anyway.
  • Marcos Aguayo
    Marcos Aguayo about 11 years
    I want the extension in Django to filter on server side, not on client-side.
  • catherine
    catherine about 11 years
    @MarcosAguayo there is conflict in handle_uploaded_song, try to put it before handle_uploaded_song
  • Silas Ray
    Silas Ray about 11 years
    Why? If you are only filtering by file extension, you aren't protecting yourself in any real way from having bad or malicious data written to the system, but you are going to still have to deal with all the performance impacts of larger size requests since you didn't filter on the client. It's really the worst of both worlds.
  • catherine
    catherine about 11 years
    @MarcosAguayo rename the file variable because it use by Django
  • Marcos Aguayo
    Marcos Aguayo about 11 years
    I know, but I'm new using Django and this solution is easier. Thanks anyway
  • user875139
    user875139 almost 9 years
    Where did you get docfile in docfile.name from?
  • dleal
    dleal almost 9 years
    Well, it was a mistake, should be file, which is being checked just in the previous line. Probably copy-paste error, sorry :)
  • Pran Kumar Sarkar
    Pran Kumar Sarkar almost 4 years
    @Marceio Soares This is not working in guessing pdf extension from request.data.
  • Marcelo Soares
    Marcelo Soares almost 4 years
    @PranKumarSarkar Are you sure the PDF file are you used is working correctly? What version of Python do you used? I am just tried using Python version 3.6.9 with a PDF file in my computer and worked fine.
  • Pran Kumar Sarkar
    Pran Kumar Sarkar almost 4 years
    Python 3.7 I was not guessing the pdf file extension from storage. I was trying to check it in django backend from in-memory file request.data.get('filenamefield')
  • Evgeny Malkov
    Evgeny Malkov about 3 years
    It's weird that this answer is marked as correct - it checks only filename, answer below with magic_numbers check is much more better and secure way