今天终于是抽时间完成了后台上传图片的功能,确切的说是上传文件的功能。终于可以在blog方便的插入自己的图片了,之前不做这个功能是觉得服务器在国外,弄个图片上去图片的加载速度应该会很慢,会让人产生这个网站很慢的错觉。
前一段时间又拍云给了个邮件,请求资源置换,具体方案就是我博客下方放他们一个链接,然后我就有了个不限期的存储空间。我觉得应该算是互相得益的交易。 这里也广播下,欢迎其他资源提供商前来洽谈,^_^。
说回正题,如果只是存在自己服务器上,那就挺简单了,只用个FileField或者ImageField,然后django自己的后台就搞定了,如果有像我这样需求的话,就要使用自定义的storage了。官方文档参考这里: https://docs.djangoproject.com/en/1.5/howto/custom-file-storage/。
自定义的storage也很简单,只要实现storage的几个方法就行了,主要是_save:
.. code:: python
import upyun
from django.db import models
from django.core.files.storage import Storage
from django.utils.six.moves.urllib.parse import urljoin
from django.utils.encoding import filepath_to_uri
class UpyunStorage(Storage):
BUCKETNAME = 'xxxx'
USERNAME = 'the5fire'
PASSWORD = 'xxxxxx'
BASE_URL = "http://xxxxx.b0.upaiyun.com"
up = upyun.UpYun(BUCKETNAME, USERNAME, PASSWORD, timeout=30,
endpoint=upyun.ED_AUTO)
def _save(self, name, content):
full_url = self.BASE_URL + name
try:
res = self.up.put(name, content.read(), checksum=False)
except Exception as e:
raise
return full_url
def exists(self, name):
try:
self.up.getinfo(name)
except Exception:
return False
return True
def listdir(self, path):
pass
def size(self, name):
return 0
def url(self, name):
return urljoin(self.BASE_URL, filepath_to_uri(name))
class StaticFile(models.Model):
name = models.CharField(max_length=40, blank=True, verbose_name=u'名称')
url = models.FileField(upload_to="/staticfile", storage=UpyunStorage(), verbose_name=u'URL')
create_time = models.DateTimeField(u'创建时间', auto_now_add=True)
就这么个代码就ok了,需求比较简单。另外也重写了对应的admin list页面,有同样需求的同学可以参考下,因为我想在列表页直接上传文件,而不是每次都要进入增加的页面。这个需求主要有两个地方需要重写,一是对应staticfile的admin类,二是对应的change_list.html这个模板(在django/contrib/admin/templates/admin下)。对应的代码如下:
admin.py:
.. code:: python
#coding:utf-8
from django.contrib import admin
from .models import StaticFile
class StaticFileAdmin(admin.ModelAdmin):
change_list_template = "admin/model_list.html" # 就是它
search_fields = ('name', 'url')
fields = ('name', 'url')
list_display = ('name', 'url', 'create_time')
actions_on_top = False
admin.site.register(StaticFile, StaticFileAdmin)
model_list.html:
.. code:: html
{% extends "admin/change_list.html" %}
{% block filters %}
<div>
<h6>文件上传:</h6>
<form enctype="multipart/form-data" action="add/" method="post" id="staticfile_form">
{% csrf_token %}
<label for="id_name">名称:</label>
<input class="vTextField" id="id_name" maxlength="40" name="name" type="text" />
<label for="id_url" class="required">URL:</label>
<input id="id_url" name="url" type="file" />
<input type="submit" value="保存" name="_save" />
</form>
</div>
<br/>
<br/>
{{ super }}
{% endblock %}
最后的界面是这个样子的:
PS:刚才在又拍云后台发现可以设置防盗链,如果你复制了这篇文章的图文到你的空间,图片是无法访问的,如果有需求可以与我联系。
- from the5fire.com微信公众号:Python程序员杂谈