上传图片的写法
<form id="uploadAvatarForm" action="{% url "upl:upload" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" id="uploadAvatar" name="uploadavatarfile">
<input type="submit" value="submit">
</form>
form的写法
注意enctype的格式,上传文件需要添加{% csrf_token %}。
from functools import wraps
UPLOAD_AVATAR_TEXT = {
'CHOOSE_IMAGE': 'Choose Image',
'CROP_IMAGE': 'Crop',
'TEST_FUNC_NOT_PASSED': 'Forbidden',
'INVALID_IMAGE': 'Invalid File, Please choose an image',
'NO_IMAGE': 'Please upload image',
'TOO_LARGE': 'File Too Large, choose a smaller one',
'SUCCESS': 'Success',
'ERROR': 'Error, try later',
}
def test_func(request):
return request.method == 'POST' and request.user.is_authenticated()
def protected(func)://装饰符
@wraps(func)
def decorator(request, *args, **kwargs):
if not test_func(request):
return HttpResponse(
"<script>window.parent.upload_avatar_error('%s')</script>" % UPLOAD_AVATAR_TEXT['TEST_FUNC_NOT_PASSED']
)
try:
return func(request, *args, **kwargs)
except UploadAvatarError as e:
return HttpResponse(
"<script>window.parent.upload_avatar_error('%s')</script>" % e
)
return decorator
UPLOAD_AVATAR_MAX_SIZE = 1024 * 1024 * 3
import os
import time
import hashlib
CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
PROJECT_PATH = os.path.dirname(CURRENT_PATH)
ROOT_PATH = os.path.dirname(PROJECT_PATH)
UPLOAD_AVATAR_UPLOAD_ROOT = os.path.join(PROJECT_PATH, 'templates/upload')
@protected
def upload(request):
try:
uploaded_file = request.FILES['uploadavatarfile']
except KeyError:
raise UploadAvatarError(UPLOAD_AVATAR_TEXT['INVALID_IMAGE'])
if uploaded_file.size > UPLOAD_AVATAR_MAX_SIZE:
raise UploadAvatarError(UPLOAD_AVATAR_TEXT['TOO_LARGE'])
name, ext = os.path.splitext(uploaded_file.name)
new_name = hashlib.md5('%s%f' %(get_random_string(), time.time())).hexdigest()
new_name = '%s%s' % (new_name, ext.lower())
fpath = os.path.join(UPLOAD_AVATAR_UPLOAD_ROOT, new_name)
with open(fpath, 'w') as f:
for c in uploaded_file.chunks(10240):
f.write(c)
try:
Image.open(fpath)
except IOError:
try:
os.unlink(fpath)
except:
pass
raise UploadAvatarError(UPLOAD_AVATAR_TEXT['INVALID_IMAGE'])
if UploadedImage.objects.filter(uid=get_uid(request)).exists():
old_name = UploadedImage.objects.get(uid=get_uid(request)).image
old_path = os.path.join(UPLOAD_AVATAR_UPLOAD_ROOT, old_name)
os.unlink(old_path)//从文件夹删除旧图片
UploadedImage.objects.filter(uid=get_uid(request)).update(image=new_name)
else:
UploadedImage.objects.create(uid=get_uid(request), image=new_name)
return HttpResponse("success")
调用头像:
def welcome(request):
s = UploadedImage.objects.get(uid=get_uid(request))
imgs = "<p><img src='%s'/></p>" % (UPLOAD_AVATAR_URL_PREFIX_ORIGINAL + s.image)
return render_to_response('welcome.html', {'image': imgs}, context_instance=RequestContext(request))
models.py写法
class UploadedImage(models.Model):
uid = models.IntegerField(unique=True)
image = models.CharField(max_length=255)
upload_date = models.DateTimeField(auto_now_add=True)
def get_image_path(self):
path = os.path.join(UPLOAD_AVATAR_UPLOAD_ROOT, self.image)
if not os.path.exists(path):
return None
return path
特别注意
settings.py中STATIC_URL 决定访问路径,STATICFILES_DIRS设置访问路径包括的文件夹。
例如STATICFILES_DIRS = (
'templates',
os.path.join(os.path.dirname(__file__), '..', 'static'),
)
STATIC_URL = '/te/'
则UPLOAD_AVATAR_URL_PREFIX_ORIGINAL = '/te/upload/'
可以没有te文件夹。只要根目录下有templates文件夹就可,然后下面有个二级子目录upload。
图片的html页面{% autoescape off %}
{{ image }}
{% endautoescape %}否则会显示转义符