the5fire的技术博客

关注python、vim、linux、web开发和互联网--life is short, we need python.


django自定义后台图片上传

作者:the5fire | 标签:       | 发布:2013-11-04 4:31 a.m. | 阅读量: 7120, 6968

今天终于是抽时间完成了后台上传图片的功能,确切的说是上传文件的功能。终于可以在blog方便的插入自己的图片了,之前不做这个功能是觉得服务器在国外,弄个图片上去图片的加载速度应该会很慢,会让人产生这个网站很慢的错觉。

前一段时间又拍云给了个邮件,请求资源置换,具体方案就是我博客下方放他们一个链接,然后我就有了个不限期的存储空间。我觉得应该算是互相得益的交易。 这里也广播下,欢迎其他资源提供商前来洽谈,^_^。

说回正题,如果只是存在自己服务器上,那就挺简单了,只用个FileField或者ImageField,然后django自己的后台就搞定了,如果有像我这样需求的话,就要使用自定义的storage了。官方文档参考这里: 轻戳

自定义的storage也很简单,只要实现storage的几个方法就行了,主要是_save:

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:

#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:

{% 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 %}

最后的界面是这个样子的:

http://the5fireblog.b0.upaiyun.com/staticfile/Snip20131103_7.png

PS:刚才在又拍云后台发现可以设置防盗链,如果你复制了这篇文章的图文到你的空间,图片是无法访问的,如果有需求可以与我联系。


----EOF-----

扫码关注,或者搜索微信公众号:码农悟凡


其他分类: