django-ckeditor 上传图片的绝对路径
Absolute paths on images uploaded by django-ckeditor
我将 django-rest-framework
与 django-ckeditor
结合使用。我正在使用绝对 url-s 提供一些图像,没有任何问题。但是ckeditor上传的图片和文件都是以相对路径的方式,客户端不能显示,因为是不同的域。
这是我得到的示例:
{
image: "http://example.com/media/myimage.png",
body: "<p><a href=\"/media/ckeditor/myfile.pdf\">download my file</a></p>"
}
这就是我想要得到的:
{
image: "http://example.com/media/myimage.png",
body: "<p><a href="http://example.com/media/ckeditor/myfile.pdf\">download my file</a></p>"
}
编辑:
这将是我的示例的模型:
from django.db import models
from ckeditor_uploader.fields import RichTextUploadingField
image: models.ImageField()
body: RichTextUploadingField(blank=True,null=True)
我会使用自定义序列化程序来解决这个问题:
from rest_framework import serializers
def relative_to_absolute(url):
return 'http://127.0.0.1:8000' + url
class FileFieldSerializer(serializers.Field):
def to_representation(self, value):
url = value.url
if url and url.startswith('/'):
url = relative_to_absolute(url)
return url
当 filefield.url 包含亲戚 url 时,会调用 relative_to_absolute() 来添加域名。
这里我只是用了一个常量字符串;您可以将其保存在您的设置中,或者,如果安装了 Django Site 框架,则按如下方式检索它:
from django.contrib.sites.models import Site
domain=Site.objects.get_current().domain
自定义序列化程序的示例用法:
class Picture(BaseModel):
...
image = models.ImageField(_('Image'), null=True, blank=True)
...
class PictureSerializer(serializers.ModelSerializer):
image = FileFieldSerializer()
class Meta:
model = Picture
fields = '__all__'
RichTextUploadingField 的变体
另一方面,如果您使用 CKEditor 的 RichTextUploadingField,则您的字段基本上是一个 TextField,其中 HTML 片段保存在图像上
上传。
在此 HTML 片段中,CKEditor 将使用相对路径引用上传的图像,原因非常充分:
- 如果更改域,您的网站仍然可以工作
- 开发实例将在本地主机中运行
- 毕竟,我们使用的是 Django,而不是 WordPress ;)
所以,我不会碰它,而是在运行时在自定义序列化程序中修复路径:
SEARCH_PATTERN = 'href=\"/media/ckeditor/'
SITE_DOMAIN = "http://127.0.0.1:8000"
REPLACE_WITH = 'href=\"%s/media/ckeditor/' % SITE_DOMAIN
class FixAbsolutePathSerializer(serializers.Field):
def to_representation(self, value):
text = value.replace(SEARCH_PATTERN, REPLACE_WITH)
return text
或者,域可以保存在设置中:
from django.conf import settings
REPLACE_WITH = 'href=\"%s/media/ckeditor/' % settings.SITE_DOMAIN
或从 Django Site 框架中检索如下:
from django.contrib.sites.models import Site
REPLACE_WITH = 'href=\"{scheme}{domain}/media/ckeditor/'.format(
scheme="http://",
domain=Site.objects.get_current().domain
)
您可能需要根据您的 CKEditor 配置调整 SEARCH_PATTERN
;越具体越好
示例用法:
class Picture(BaseModel):
...
body = RichTextUploadingField(blank=True,null=True)
...
class PictureSerializer(serializers.ModelSerializer):
body = FixAbsolutePathSerializer()
class Meta:
model = Picture
fields = '__all__'
我将 django-rest-framework
与 django-ckeditor
结合使用。我正在使用绝对 url-s 提供一些图像,没有任何问题。但是ckeditor上传的图片和文件都是以相对路径的方式,客户端不能显示,因为是不同的域。
这是我得到的示例:
{
image: "http://example.com/media/myimage.png",
body: "<p><a href=\"/media/ckeditor/myfile.pdf\">download my file</a></p>"
}
这就是我想要得到的:
{
image: "http://example.com/media/myimage.png",
body: "<p><a href="http://example.com/media/ckeditor/myfile.pdf\">download my file</a></p>"
}
编辑: 这将是我的示例的模型:
from django.db import models
from ckeditor_uploader.fields import RichTextUploadingField
image: models.ImageField()
body: RichTextUploadingField(blank=True,null=True)
我会使用自定义序列化程序来解决这个问题:
from rest_framework import serializers
def relative_to_absolute(url):
return 'http://127.0.0.1:8000' + url
class FileFieldSerializer(serializers.Field):
def to_representation(self, value):
url = value.url
if url and url.startswith('/'):
url = relative_to_absolute(url)
return url
当 filefield.url 包含亲戚 url 时,会调用 relative_to_absolute() 来添加域名。
这里我只是用了一个常量字符串;您可以将其保存在您的设置中,或者,如果安装了 Django Site 框架,则按如下方式检索它:
from django.contrib.sites.models import Site
domain=Site.objects.get_current().domain
自定义序列化程序的示例用法:
class Picture(BaseModel):
...
image = models.ImageField(_('Image'), null=True, blank=True)
...
class PictureSerializer(serializers.ModelSerializer):
image = FileFieldSerializer()
class Meta:
model = Picture
fields = '__all__'
RichTextUploadingField 的变体
另一方面,如果您使用 CKEditor 的 RichTextUploadingField,则您的字段基本上是一个 TextField,其中 HTML 片段保存在图像上 上传。
在此 HTML 片段中,CKEditor 将使用相对路径引用上传的图像,原因非常充分:
- 如果更改域,您的网站仍然可以工作
- 开发实例将在本地主机中运行
- 毕竟,我们使用的是 Django,而不是 WordPress ;)
所以,我不会碰它,而是在运行时在自定义序列化程序中修复路径:
SEARCH_PATTERN = 'href=\"/media/ckeditor/'
SITE_DOMAIN = "http://127.0.0.1:8000"
REPLACE_WITH = 'href=\"%s/media/ckeditor/' % SITE_DOMAIN
class FixAbsolutePathSerializer(serializers.Field):
def to_representation(self, value):
text = value.replace(SEARCH_PATTERN, REPLACE_WITH)
return text
或者,域可以保存在设置中:
from django.conf import settings
REPLACE_WITH = 'href=\"%s/media/ckeditor/' % settings.SITE_DOMAIN
或从 Django Site 框架中检索如下:
from django.contrib.sites.models import Site
REPLACE_WITH = 'href=\"{scheme}{domain}/media/ckeditor/'.format(
scheme="http://",
domain=Site.objects.get_current().domain
)
您可能需要根据您的 CKEditor 配置调整 SEARCH_PATTERN
;越具体越好
示例用法:
class Picture(BaseModel):
...
body = RichTextUploadingField(blank=True,null=True)
...
class PictureSerializer(serializers.ModelSerializer):
body = FixAbsolutePathSerializer()
class Meta:
model = Picture
fields = '__all__'