Django文件上传:返回带域名URL地址

在Django中,默认的文件上传(如ImageField)返回的是文件的相对路径,而有些前后端分离的项目需要提供完整域名地址以正确显示上传的文件,特别是在使用ckeditor-uploader进行图片上传时。以下是两种情景的解决方法:

一、Django默认ImageField上传图片

    Django上传图片时并不是直接存储图片,而是存储图片的唯一标识,再通过标识去获取图片,Django中上传图片的字段类型是ImageField。

1.写一个上传图片的models

<code>class SKUImage(BaseModel):</code><code> sku = models.ForeignKey(SKU, on_delete=models.CASCADE, verbose_name='sku')</code><code> image = models.ImageField(verbose_name='图片') # 存储图片</code><code><br></code><code> class Meta:</code><code> db_table = 'tb_sku_image'</code><code><br></code><code> def __str__(self):</code><code> return '%s %s' % (self.sku.name, self.id)</code>
图片[1]-Django文件上传:返回带域名URL地址-山海云端论坛

ImageField类型有一个url属性,返回图片的URL链接,即图片标识。如果想要一个带域名完整的URL地址,需要自定义存储后端,并改写url()函数返回完整图片地址

2.自定义存储后端

新建utils.py,新建一个类让其继承Storage,并重写url()方法,把该方法的name参数拼接上自定义的域名地址再返回

<code>from django.core.files.storage import Storage</code><code><br></code><code>class UrlStorage(Storage):</code><code> def _open(self,name,mode='rb'):</code><code> # 打开django本地文件</code><code> pass</code><code> def _save(self,name,content,max_length=None):</code><code> # 上传图片</code><code> pass</code><code> # 给返回的图片标识加上前缀</code><code> def url(self, name):</code><code> return "http://image.mysite.site:8888/" + name</code>

3.修改setting.py配置文件,增加如下设置,告诉Django要使用自定义的存储后端

<code><em># 指定自定义的Django文件存储类</em></code><code>DEFAULT_FILE_STORAGE = 'utils.UrlStorage'</code>

上述就可以实现Django默认图片上传返回带域名的url地址

二、ckeditor-uploader上传图片

找到ckeditor-uploer安装路径修改views.py文件,即../site-packages/ckeditor-uploader/views.py
然后找到下面这段代码:

<code>class ImageUploadView(generic.View):</code><code> http_method_names = ["post"]</code><code><br></code><code> def post(self, request, **kwargs):</code><code> """</code><code> Uploads a file and send back its URL to CKEditor.</code><code> """</code><code> uploaded_file = request.FILES["upload"]</code><code><br></code><code> backend = get_backend()</code><code><br></code><code> ck_func_num = request.GET.get("CKEditorFuncNum")</code><code> if ck_func_num:</code><code> ck_func_num = escape(ck_func_num)</code><code><br></code><code> filewrapper = backend(storage, uploaded_file)</code><code> allow_nonimages = getattr(settings, "CKEDITOR_ALLOW_NONIMAGE_FILES", True)</code><code> <em># Throws an error when an non-image file are uploaded.</em></code><code> if not filewrapper.is_image and not allow_nonimages:</code><code> return HttpResponse(</code><code> """</code><code> <script type='text/javascript'></code><code> window.parent.CKEDITOR.tools.callFunction({}, '', 'Invalid file type.');</code><code> </script>""".format(</code><code> ck_func_num</code><code> )</code><code> )</code><code><br></code><code> filepath = get_upload_filename(uploaded_file.name, request)</code><code><br></code><code> saved_path = filewrapper.save_as(filepath)</code><code><br></code><code> url = utils.get_media_url(saved_path)</code><code><br></code><code> if ck_func_num:</code><code> <em># Respond with Javascript sending ckeditor upload url.</em></code><code> return HttpResponse(</code><code> """</code><code> <script type='text/javascript'></code><code> window.parent.CKEDITOR.tools.callFunction({}, '{}');</code><code> </script>""".format(</code><code> ck_func_num, url</code><code> )</code><code> )</code><code> else:</code><code> _, filename = os.path.split(saved_path)</code><code> retdata = {"url": url, "uploaded": "1", "fileName": filename}</code><code> return JsonResponse(retdata)</code><code><br></code><code>......</code><code><br></code><code>def get_files_browse_urls(user=None):</code><code> """</code><code> Recursively walks all dirs under upload dir and generates a list of</code><code> thumbnail and full image URL's for each file found.</code><code> """</code><code> files = []</code><code> for filename in get_image_files(user=user):</code><code> src = utils.get_media_url(filename)</code><code> if getattr(settings, "CKEDITOR_IMAGE_BACKEND", None):</code><code> if is_valid_image_extension(src):</code><code> thumb = utils.get_media_url(utils.get_thumb_filename(filename))</code><code> else:</code><code> thumb = utils.get_icon_filename(filename)</code><code> visible_filename = os.path.split(filename)[1]</code><code> if len(visible_filename) > 20:</code><code> visible_filename = visible_filename[0:19] + "..."</code><code> else:</code><code> thumb = src</code><code> visible_filename = os.path.split(filename)[1]</code><code> files.append(</code><code> {</code><code> "thumb": thumb,</code><code> "src": src,</code><code> "is_image": is_valid_image_extension(src),</code><code> "visible_filename": visible_filename,</code><code> }</code><code> )</code><code><br></code><code> return files</code>

将代码中的url、src进行修改,添加域名或服务器地址,拼接带域名的返回值地址。

<code>url = utils.get_media_url(saved_path)</code><code>替换成</code><code>url = 'http://127.0.0.1:8000'+ utils.get_media_url(saved_path)</code><code>src = utils.get_media_url(filename)</code><code>替换成</code><code>src = 'http://127.0.0.1:8000'+ utils.get_media_url(filename)</code>

然后就成功实现。

图片[2]-Django文件上传:返回带域名URL地址-山海云端论坛
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容