前言
为什么要开发这个功能?因为当时我在利用django搭建好自己的博客时,通过后台来发表文章时,需要上传文章封面,我的文章封面是单独定义一个字段也就是ImageField来上传封面,但是有的时候我可能好几篇文章都是同一个封面,这个时候不可能在上传一遍之前已经上传过了的封面了,有点浪费服务器空间,所以当时就想着要自定义个field来实现上面功能。
废话不多说先看看实现后的效果
新建django应用,
执行下面命令,新建一个应用名为uploader
startapp uploader
目录结构如下
│ localapps.py
│ fields.py
│ widgets.py
│ init.py
│
├─migrations
│ │ _init.py
│
├─static
│ └─uploader
│ │ jquery.fileupload.js
│ │ uploader.css
│ │ uploader.js
│ │
│ └─images
│ add.png
│ bg.png
│ dialog-title-bg.png
│ image.png
│ success.gif
│ success.png
│
├─templates
│ image.html
新建fields.py
from django import forms
from django.db import models
class UploaderTextField(models.CharField):
def __init__(self,*args,**kwargs):
super(UploaderTextField, self).__init__(*args, **kwargs)
def formfield(self, **kwargs):
defaults = {
'form_class': self._get_form_class(),
}
defaults.update(kwargs)
return super(UploaderTextField,self).formfield(**defaults)
@staticmethod
def _get_form_class():
return UploaderFormField
class UploaderFormField(forms.CharField):
def __init__( self,*args,**kwargs):
from .widgets import UploaderWidget
kwargs.update({"widget":UploaderWidget()})
super(UploaderFormField, self).__init__(*args, **kwargs)
新建widgets.py
from django import forms
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
class UploaderWidget(forms.TextInput):
def __init__(self,*args, **kwargs):
super(UploaderWidget, self).__init__(*args, **kwargs)
def render(self,name,value,attrs=None, renderer=None):
value='' if value is None else value
final_attrs = self.build_attrs(self.attrs, attrs, name=name)
context = {
'value':value,
'id': final_attrs['id'],
'name':name,
'label':self.attrs.get('label', name)
}
return mark_safe(render_to_string('image.html',context))
def build_attrs(self, base_attrs, extra_attrs=None, **kwargs):
attrs = dict(base_attrs, **kwargs)
if extra_attrs:
attrs.update(extra_attrs)
return attrs
class Media:
js = ("uploader/image.js","uploader/jquery.fileupload.js",)
css = {"all": ("uploader/image.css",)}
新建image.html
{% load static %}
<a href="{{ value }}" target="_blank" title="{{ label }}">
<img src="{{ value }}" class="field_img">
</a><br>更改:
<input type="file" data-toggle="modal" data-target="#uploaderModal">
<input type="hidden" name="{{ name }}" value="{{ value }}" id="{{ id }}">
<!-- 模态框(Modal) -->
<div class="modal fade" id="uploaderModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">图片上传</h4>
</div>
<div class="modal-body uploader">
<div class="wrapper">
<div id="tabhead" class="tabhead">
<span class="tab focus" data-content-id="remote">插入图片</span>
<span class="tab" data-content-id="upload">本地上传</span>
<span class="tab" data-content-id="online">在线管理</span>
<span class="tab" data-content-id="search">图片搜索</span>
</div>
<div id="tabbody" class="tabbody">
<div id="remote" class="panel focus">
<label for="url">地 址:</label>
<input class="text" id="url" type="text">
<div id="preview"></div>
</div>
<!-- 上传图片 -->
<div id="upload" class="panel">
<div class="file-button" id="upload_image">
<input type="file" name="upfile" id="fileupload">
</div>
</div>
<!-- 在线图片 -->
<div id="online" class="panel">
<div id="imageList">图片加载中……</div>
</div>
<!-- 搜索图片 -->
<div id="search" class="panel">
<div class="searchBar">
<input id="searchTxt" class="searchTxt text" type="text">
<select id="searchType" class="searchType" title="图片类型">
<option value=".jpg">jpg</option>
<option value=".png">png</option>
</select>
<input id="searchReset" type="button" value="清空搜索">
<input id="searchBtn" type="button" value="百度一下">
</div>
<div id="searchList" class="searchList"><ul id="searchListUl"></ul></div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭
</button>
<button type="button" class="btn btn-primary" id="ok">确认</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
<script>
$(function () {
$("#{{ id }}").uploader({"uploadUrl":"图片上传接口","deleteUrl":"图片删除接口","searchUrl":"图片搜索接口","queryUrl":"图片查询接口"});
})
</script>