摘要:公司项目使用七牛云存储文件,而项目控制台基于DjangoAdmin开发,现在有个需求要在控制台中直接上传文件到七牛,所以自己就写了一个DjangoAPP:qiniu_fields用来实现这个功能。这里记录&;分享一下。一、技术方案Django本身支持自定义Model字段,为了实现需求,我在URLField和TextField的基础上实现自定义字段,同时重写其对应的Widget。二、qiniu_fieldsAPP具体代码如下:widgets.py#!-*-coding:
公司项目使用七牛云存储文件,而项目控制台基于 Django Admin 开发,现在有个需求要在控制台中直接上传文件到七牛,所以自己就写了一个 Django APP:qiniu_fields 用来实现这个功能。这里记录 &; 分享一下。
一、技术方案
Django 本身支持自定义 Model 字段,为了实现需求,我在 URLField 和 TextField 的基础上实现自定义字段,同时重写其对应的 Widget。
二、qiniu_fields APP
具体代码如下:
widgets.py
#! -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from django.utils.html import smart_urlquote
class QiniuFileWidget(forms.URLInput):
input_type = 'file'
template_name = 'file.html'
def __init__(self, attrs=None):
final_attrs = {
'domain': settings.QINIU_DOMAIN,
'uptoken_url': settings.QINIU_UPTOKEN_URL,
}
if attrs is not None:
final_attrs.update(attrs)
super(QiniuFileWidget, self).__init__(attrs=final_attrs)
def get_context(self, name, value, attrs):
context = super(QiniuFileWidget, self).get_context(name, value, attrs)
context['current_label'] = '当前:'
context['widget']['href'] = smart_urlquote(context['widget']['value']) if value else ''
return context
@property
def media(self):
return forms.Media(js=('qiniu_fields/plupload/plupload.full.min.js', 'qiniu_fields/plupload/i18n/zh_CN.js',
'qiniu_fields/qiniu/qiniu.min.js', 'qiniu_fields/qiniu/ui.min.js'))
# class Media:
# js = ('qiniu_fields/plupload/plupload.full.min.js', 'qiniu_fields/plupload/i18n/zh_CN.js',
# 'qiniu_fields/qiniu/qiniu.min.js', 'qiniu_fields/qiniu/ui.min.js')
class QiniuFileListWidget(forms.Textarea):
template_name = 'file_list.html'
def __init__(self, attrs=None):
final_attrs = {
'domain': settings.QINIU_DOMAIN,
'uptoken_url': settings.QINIU_UPTOKEN_URL,
}
if attrs is not None:
final_attrs.update(attrs)
super(QiniuFileListWidget, self).__init__(attrs=final_attrs)
@property
def media(self):
return forms.Media(js=('qiniu_fields/plupload/plupload.full.min.js', 'qiniu_fields/plupload/i18n/zh_CN.js',
'qiniu_fields/qiniu/qiniu.min.js', 'qiniu_fields/qiniu/ui.min.js'))
# class Media:
# js = ('qiniu_fields/plupload/plupload.full.min.js', 'qiniu_fields/plupload/i18n/zh_CN.js',
# 'qiniu_fields/qiniu/qiniu.min.js', 'qiniu_fields/qiniu/ui.min.js')
forms.py
#! -*- coding: utf-8 -*-
from django import forms
from .widgets import QiniuFileWidget, QiniuFileListWidget
class QiniuFileFormField(forms.URLField):
prefix = ''
file_type = 'all'
widget = QiniuFileWidget
def __init__(self, *args, **kwargs):
kwargs["widget"] = QiniuFileWidget(attrs={'prefix': self.prefix, 'file_type': self.file_type})
super(QiniuFileFormField, self).__init__(*args, **kwargs)
fields.py
#! -*- coding: utf-8 -*-
from django.db import models
from .widgets import QiniuFileWidget, QiniuFileListWidget
from .forms import QiniuFileFormField
class QiniuFileField(models.URLField):
widget_clz = QiniuFileWidget
form_field_clz = QiniuFileFormField
def __init__(self, verbose_name=None, name=None, prefix='', file_type='all', **kwargs):
self.prefix = prefix
self.file_type = file_type
kwargs['max_length'] = 500
super(QiniuFileField, self).__init__(verbose_name, name, **kwargs)
def formfield(self, **kwargs):
self.form_field_clz.prefix = self.prefix
self.form_field_clz.file_type = self.file_type
kwargs.update({
'form_class': self.form_field_clz,
'widget': self.widget_clz(attrs={'prefix': self.prefix, 'file_type': self.file_type})
})
return super(QiniuFileField, self).formfield(**kwargs)
class QiniuFileListField(models.TextField):
def __init__(self, *args, prefix='', file_type='all', **kwargs):
self.prefix = prefix
self.file_type = file_type
super(QiniuFileListField, self).__init__(*args, **kwargs)
def formfield(self, **kwargs):
kwargs.update({
'widget': QiniuFileListWidget(attrs={'prefix': self.prefix, 'file_type': self.file_type}),
})
return super(QiniuFileListField, self).formfield(**kwargs)
三、项目Demo
Django Qiniu Fields代码和 Demo 项目见Github:django-qiniu-fields
Over!