摘要:公司項目使用七牛云存儲文件,而項目控制臺基于DjangoAdmin開發(fā),現(xiàn)在有個需求要在控制臺中直接上傳文件到七牛,所以自己就寫了一個DjangoAPP:qiniu_fields用來實現(xiàn)這個功能犀农。這里記錄&;分享一下厕氨。一、技術方案Django本身支持自定義Model字段,為了實現(xiàn)需求,我在URLField和TextField的基礎上實現(xiàn)自定義字段,同時重寫其對應的Widget李根。二、qiniu_fieldsAPP具體代碼如下:widgets.py#!-*-coding:
公司項目使用七牛云存儲文件,而項目控制臺基于 Django Admin 開發(fā),現(xiàn)在有個需求要在控制臺中直接上傳文件到七牛,所以自己就寫了一個 Django APP:qiniu_fields 用來實現(xiàn)這個功能笨触。這里記錄 &; 分享一下裕菠。
一妄壶、技術方案?
Django 本身支持自定義 Model 字段,為了實現(xiàn)需求,我在 URLField 和 TextField 的基礎上實現(xiàn)自定義字段,同時重寫其對應的 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!