九、用户文件上传下载
(一)、后台数据库上传文件
设置上传文件的上传位置,settings.py 中设置
MEDIA_URL = '/media/' # MEDIA_URL是指从浏览器访问时的地址前缀 MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 上传文件保存的根目录
上下文处理说明,settings.py 中设置
TEMPLATES = [ ...... 'OPTIONS': { 'context_processors': [ ...... 'django.core.context_processors.media', ......
上传文件访问url设置,urls.py中设置
from django.views.static import serve from mxonline2.settings import MEDIA_ROOT urlpatterns = [ ...... # 配置上传文件的访问处理函数 url(r'^media/(?P<path>.*)$',serve,{"document_root":MEDIA_ROOT}) ...... ]
html文件中访问
<img data-url="{{ MEDIA_URL }}{{ org.image}} /> # org指的是一个对象的实例
(二)、用户上传文件
定义modelform
class UploadImageModelForm(forms.ModelForm): #定义modelform class Meta: model=UserProfile fields=['image',]
url配置
# 修改头像 url(r'^upload/image/$', UploadImageView.as_view(), name='upload_image'),
定义View
class UploadImageView(LoginRequiredMixin,View): def post(self,request): # 上传文件必须传request.FILES参数,instance保证modelform.save()时,是进行update() image_form = UploadImageModelForm(request.POST,request.FILES,instance=request.user) if image_form.is_valid(): image_form.save() # 会调用model.save()方法 return HttpResponse(json.dumps({'status': 'success'}), content_type='application/json') return HttpResponse(json.dumps({'status': 'fail'}), content_type='application/json') # 另外一种更改数据库图像的方法 # image_form = UploadImageModelForm(request.POST,request.FILES) # 不上传instance实例 # if image_form.is_valid(): # image=image_form.cleaned_data['image'] # request.user.image=image # request.user.save()
html文件(form表单)
<form class="clearfix" id="jsAvatarForm" enctype="multipart/form-data" autocomplete="off" method="post" action="{% url 'user_center:upload_image' %}" target='frameFile'> <label class="changearea" for="avatarUp"> <span id="avatardiv" class="pic"> <img width="100" height="100" class="js-img-show" id="avatarShow" src="{{ MEDIA_URL }}{{ user.image }}"/> </span> <span class="fl upload-inp-box" style="margin-left:70px;"> <span class="button btn-green btn-w100" id="jsAvatarBtn">修改头像</span> <input type="file" name="image" id="avatarUp" class="js-img-up"/> </span> </label> {% csrf_token %} </form>
(三)、用户下载资料
<li>
<span><i class="aui-iconfont aui-icon-file"></i> {{ resource.name }}</span>
<a href="{{ MEDIA_URL }}{{ resource.resource_file }}" # 链接文件的路径,
class="downcode" target="_blank" download="" data-id="274" title="">下载</a>
</li>
十、xadmin集成富文本编辑器
参考网址:https://github.com/zhangfisher/DjangoUeditor
一、安装
1. pip install DjangoUeditor 或者运行:python setup.py install 方法安装。但可能会出现各种问题,建议直接将原码复制到项目的方法安装
2. 在Django中安装DjangoUeditor 在INSTALL_APPS里面增加DjangoUeditor app,如下: INSTALLED_APPS = ( #…….. ‘DjangoUeditor’, )
3. 配置urls url(r’^ueditor/’,include(‘DjangoUeditor.urls’ )),
4. 在models中的使用:
from DjangoUeditor.models import UEditorField
class Blog(models.Model):
Name=models.CharField(,max_length=100,blank=True)
Content=UEditorField(u'内容 ',width=600, height=300, toolbars="full", imagePath="", filePath="", upload_settings={"imageMaxSize":1204000},
settings={},command=None,event_handler=myEventHander(),blank=True) # 部分参数可以省略,imagePath\filePath需要配置
二、xadmin文件包中配置
/xadmin/plugins/文件夹下添加 ueditor.py文件
# -*- coding: utf-8 -*- import xadmin from xadmin.views import BaseAdminPlugin, CreateAdminView, ModelFormAdminView, UpdateAdminView from DjangoUeditor.models import UEditorField from DjangoUeditor.widgets import UEditorWidget from django.conf import settings class XadminUEditorWidget(UEditorWidget): def __init__(self,**kwargs): self.ueditor_options=kwargs self.Media.js = None super(XadminUEditorWidget,self).__init__(kwargs) class UeditorPlugin(BaseAdminPlugin): def get_field_style(self, attrs, db_field, style, **kwargs): if style == 'ueditor': if isinstance(db_field, UEditorField): widget = db_field.formfield().widget param = {} param.update(widget.ueditor_settings) param.update(widget.attrs) return {'widget': XadminUEditorWidget(**param)} return attrs def block_extrahead(self, context, nodes): js = '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.config.js") #自己的静态目录 js += '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.all.min.js") #自己的静态目录 nodes.append(js) xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView) xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)
在/xadmin/plugins/init()内添加
PLUGINS = ( ...... 'ueditor' # 与ueditor.py文件名保持一致 )
三、在adminx.py相应的类中添加,如:
class CourseAdmin(object):
.....
style_fields={'detail':'ueditor'}
四、前端页面使用
出于安全的考虑,django默认将html代码转意为字符文本,而ueditor字段,按照html代码存在数据库
如:course-detail.html文件中,
......
{% autoescape off %}
{{ course.detail }}
{% endautoescape %}
......
十一、excel导入插件制作
插件制作文档:https://xadmin.readthedocs.io/en/latest/make_plugin.html
一、xadmin中添加插件文件excel.py
xadmin/plugins/excel.py
# coding:utf-8
import xadmin
from xadmin.views import BaseAdminPlugin, ListAdminView
from django.template import loader
#excel 导入
class ListImportExcelPlugin(BaseAdminPlugin):
import_excel = False
def init_request(self, *args, **kwargs):
return bool(self.import_excel)
def block_top_toolbar(self, context, nodes): # top_toolbar 为插入点名称
nodes.append(loader.render_to_string('xadmin/excel/model_list.top_toolbar.import.html', context_instance=context))
xadmin.site.register_plugin(ListImportExcelPlugin, ListAdminView)
二、xadmin中添加html模板文件
xadmin/templates/xadmin/excel/model_list.top_toobar.import.html
{% load i18n %}
<div class="btn-group export">
<a class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown" href="#">
<i class="icon-share"></i> 导入 <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li><a data-toggle="modal" data-target="#export-modal-import-excel"><i class="icon-circle-arrow-down"></i> 导入 Excel</a></li>
</ul>
<script>
function fileChange(target){
//检测上传文件的类型
var imgName = document.all.submit_upload.value;
var ext,idx;
if (imgName == ''){
document.all.submit_upload_b.disabled=true;
alert("请选择需要上传的 xls 文件!");
return;
} else {
idx = imgName.lastIndexOf(".");
if (idx != -1){
ext = imgName.substr(idx+1).toUpperCase();
ext = ext.toLowerCase( );
{# alert("ext="+ext);#}
if (ext != 'xls' && ext != 'xlsx'){
document.all.submit_upload_b.disabled=true;
alert("只能上传 .xls 类型的文件!");
return;
}
} else {
document.all.submit_upload_b.disabled=true;
alert("只能上传 .xls 类型的文件!");
return;
}
}
}
</script>
<div id="export-modal-import-excel" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">导入 Excel</h4>
</div>
<div class="modal-body">
<input type="file" onchange="fileChange(this)" name="excel" id="submit_upload">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
<button class="btn btn-success" type="submit" id="submit_upload_b"><i class="icon-share"></i> 导入</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dalog -->
</div><!-- /.modal -->
</div>
三、在/xadmin/plugins/_init_()内添加
PLUGINS = (
......
'excel' # 与excel.py文件名保持一致
)
四、将插件引入到页面,并重载post函数,如:
courses\adminx.py
class CourseAdmin(object):
......
import_excel=True # 引入插件的判断
......
def post(self, request, *args, **kwargs):
if 'excel' in request.FILES:
# 写自己的逻辑,以下为网络摘抄,未经验证
wb = xlrd.open_workbook(filename=None, file_contents=request.FILES['excel'].read())
table = wb.sheets()[0]
row = table.nrows
sql_list = []
org_id_list = []
for i in xrange(1,row):
col = table.row_values(i)
sql = Course( # 此处不应该写死,容易导入错误,应能自动识别相关顺序
degree=col[0],
learn_time=col[1],
detail=col[2],
desc=col[3],
students=col[4],
fav_nums=col[5],
name=col[6],
image=col[7],
click_nums=col[8],
course_org_id=col[10],
category=col[11],
tag=col[12],
teacher_id=col[13],
learn_what=col[14],
need_know=col[15],
notice=col[16],
is_banner=col[17],
)
sql_list.append(sql)
org_id_list.append(col[10])
Course.objects.bulk_create(sql_list)
#更新excel文件中机构包含的课程数
for id in org_id_list:
org = CourseOrg.objects.get(id=int(id))
org_course_nums = org.course_set.all().count()
org.course_nums = org_course_nums
org.save()
# 调用父类的post
return super(CourseAdmin, self).post(request, args, kwargs)