0

I use django to build my web app. And one of the page sends different files (with different file types). I have 6 file type. And my current version of code (it's really bad - that is why I write this question) is:

    try:
        file = request.FILES[u'file_doc']
    except MultiValueDictKeyError:
        try:
            file = request.FILES[u'file_fb2']
        except MultiValueDictKeyError:
            try:
                file = request.FILES[u'file_pdf']
            except MultiValueDictKeyError:
                try:
                    file = request.FILES[u'file_txt']
                except MultiValueDictKeyError:
                    try:
                        file = request.FILES[u'file_other']
                    except MultiValueDictKeyError:
                        try:
                            file = request.FILES[u'file_chm']
                        except MultiValueDictKeyError:
                            return HttpResponse('bad file type')

Could you advise me - how to improve this bad peace of code.

TIA!

Dmitry Belaventsev
  • 6,347
  • 12
  • 52
  • 75

4 Answers4

6

The in test let's you see if a key is part of a dictionary.

if u'file_doc' in request.FILES:
    file = request.FILES[u'file_doc']

You can simply loop through a set of keys to test for:

for key in (u'file_doc', u'file_fb2', .. ):
    if key in request.FILES:
        file = request.FILES[key]
        break
else:
    return HttpResponse('bad file type')

The else suite will only be executed if the for loop completed without reaching a break statement, i.e. you didn't find a matching key.

Note that you could still use your exception approach in the loop:

for key in (u'file_doc', u'file_fb2', .. ):
    try:
        file = request.FILES[key]
        break
    except MultiValueDictKeyError:
        pass
else:
    return HttpResponse('bad file type')

but I am not so sure that is more readable.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Or you could use a `try/except` inside the for loop. tomato vs Tomato -- Or, in the python world, LBYL vs EAFP... (+1) – mgilson Aug 02 '12 at 18:20
  • Thx! Firs time I afraid of long spaghetti-like try-except code:) – Dmitry Belaventsev Aug 02 '12 at 18:22
  • @mgilson: and that might be faster too (by a fraction), but I find the `in` test approach a little easier on the eye. Pick according to taste! :-) – Martijn Pieters Aug 02 '12 at 18:24
  • If the exceptional situation is the common case (and here it is), I prefer LBYL. On the other hand, if the file could be deleted between testing for it's existence and accessing it then EAFP would be the only way to go. – Steven Rumbalski Aug 02 '12 at 18:43
3

You could do something like this:

filetypes = [ u'file_doc', u'file_fb2', u'file_pdf' ]

file = None
for ft in filetypes:
  if ft in request.FILES:
    file = request.FILES[ft]
    break

if file is None:
  return HttpResponse('bad file type')
larsks
  • 277,717
  • 41
  • 399
  • 399
2

request.FILES.get(u'file_doc', DEFAULT_VALUE) will return DEFAULT_VALUE if the key does not exist in the dictionary. You can also use the in keyword as mentioned by Martijn edit see also django MultiValueDictKeyError error, how do i deal with it

Community
  • 1
  • 1
gsk
  • 558
  • 5
  • 12
1
def GetFile(request):
    file_types = "doc fb2 pdf txt other chm".split()
    for k in file_types:
        if "file_{0}".format(k) in request.FILES:
             return request.FILES["file_{0}".format(k)]

at least thats how I would do it

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179