Django 修改实现图片上传同时修改命名规则

  1 #models
  2     class Photo(models.Model):
  3         hetongNO = models.ForeignKey(HetongGL,verbose_name=u'合同号')
  4         name = models.CharField(max_length = 100,verbose_name="Name")
  5         image = models.ImageField(upload_to = "photos",blank=True,null=True)
  6 
  7     #forms
  8     class Addphoto(ModelForm):
  9         class Meta:
 10             model = Photo
 11             fields = ['hetongNO','name','image']
 12 
 13     #views
 14     import datetime
 15     import random
 16     import imghdr
 17     import os
 18     from django.conf import settings
 19     import shutil
 20 
 21     def addphoto(request):
 22         path = settings.MEDIA_ROOT + 'photo/'
 23         if request.method == 'POST':
 24 
 25             form = Addphoto(request.POST,request.FILES)
 26 
 27             if form.is_valid():
 28                 hetongNO = form.cleaned_data['hetongNO']
 29                 name = form.cleaned_data['name']
 30                 if  request.FILES: #判断是否存在上传信息,否则为空
 31 
 32                     f = request.FILES['image']
 33                     ret = handle_uploaded_file(f,path)
 34                     if ret:
 35                         p = Photo(hetongNO = hetongNO,name = name,image = ret)
 36                         p.save()
 37                         messages.add_message(request, messages.SUCCESS, '数据保存成功!')
 38                     else:
 39                         messages.add_message(request, messages.SUCCESS, '上传出现问题,请重新上传,请确保上传的文件类型正确。')
 40 
 41                 else:
 42                     p = Photo(hetongNO = hetongNO,name = name,image = None)
 43                     p.save()
 44                     messages.add_message(request, messages.SUCCESS, '数据保存成功!')
 45             return HttpResponseRedirect('/demo/')
 46 
 47         else:
 48             form = Addphoto()
 49         return render_to_response('fieldtest.html',locals(),context_instance=RequestContext(request))
 50 
 51      #将临时文件转存到指定文件夹下   
 52         def handle_uploaded_file(f,path):
 53             if f.size >= 5 * 1024 *1024 or not handle_upload_types(f.name):
 54                 return  False
 55             file_type_name_path = handle_upload_types_finally(f) #读取临时文件的列表信息。
 56             if not file_type_name_path:
 57                 return False
 58             try:
 59                 if not os.path.exists(path):
 60                     os.mkdir(path)
 61                 shutil.move(file_type_name_path[2],path) #将临时文件转存
 62                 image_path = 'photo/%s.%s' % (file_type_name_path[1],file_type_name_path[0])
 63                 return image_path
 64             except IOError:
 65                 return False
 66 
 67       #判断文件类型,如为exe则返回Flase  
 68         def handle_upload_types(file_name):
 69             file_name = unicode(file_name) #将文件原始路径转为转换编码(应对原始路径中有中文字符的情况)
 70             not_allowed_tupes = ['.exe']  #排除exe。这里想实现对文件扩展名的判断,但是没有成功,在本例中,这里实际不需要进行判断,如果上传了其他类新的文件表单会提示文件类型不符,添加这一步一是因为原代码中有,另外也想为今后处理其他文件上传积累经验。这里如何实现还请指教。
 71 
 72             for type in not_allowed_tupes:
 73                 if  file_name.endswith(type):
 74                     return False
 75                 else:
 76                     return Tru
 77         #生成临时文件
 78         def handle_upload_types_finally(f):
 79             temp_name = str(datetime.date.today().strftime("%Y%m%d")+str(random.randint(1,10000)))    #对文件进行改名,这里是按照日期加随机数生成一个文件名
 80 
 81             temp_path = settings.MEDIA_ROOT + "temp/%s" % temp_name #临时文件路径(下面创建的是一个只有文件名没有扩展名的文件)
 82             #需要先创建一个空文件然后进行写操作,很多教程都没有这一步,
 83 我一开始也没有写,但是运行的时候提示没有对应目录或文件,后来参看官方教程,
 84 发现明确使用了一个已经存在的文件,所以才这样解决的。是不是多此一举请达人们指教。
 85             try:
 86                 if not os.path.exists(temp_path):
 87                     os.mknod(temp_path)
 88             except IOError:
 89                 return False
 90             temp_file = open(temp_path, 'wb+')  #打开临时文件
 91             for chunk in f.chunks():
 92                 temp_file.write(chunk)
 93             temp_file.close()    #完成临时文件写入
 94             image_type = imghdr.what(temp_path) #判断文件类型(只能判断图片),这里有个问题,比如上传的是*.jpg,但是生成的文件为*.jpeg。
 95             if not image_type:
 96                 os.remove(temp_path)  #不是图片格式的删除临时文件
 97                 return False #如果不是图片则返回。
 98             else:
 99                 file_fullname = temp_path + '.%s' % image_type    #生成文件完全路径
100                 os.rename(temp_path,file_fullname) #将临时文件转为正常文件
101             return image_type , temp_name ,file_fullname #返回文件类型,文件名称,文件完整路径

 http://xianglong.me/article/django-request-work-flow/

这篇文章很好,很强大

posted @ 2014-11-21 00:30  爱在夕阳下  阅读(692)  评论(0编辑  收藏  举报