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/
这篇文章很好,很强大