使用 markdown 和 cloudinary 的 django 应用程序
Posted
技术标签:
【中文标题】使用 markdown 和 cloudinary 的 django 应用程序【英文标题】:django application using markdown and cloudinary 【发布时间】:2020-11-11 01:11:25 【问题描述】:我正在尝试同时使用 django-markdownx
和 dj3-cloudinary-storage
制作一个 django 应用程序。
所以django-markdownx
的功能之一是您可以将图像拖放到降价字段中,它会保存该图像并返回图像的路径。在本地,这工作得很好。将图像拖放到 makrdown 字段并按预期将其保存到 /media/markdownx/
路径,并且 markdown 字段中的图像路径是正确的。但是,在与 Cloudinary 连接后,这无法正常工作。拖放图像后,它将图像保存到 Cloudinary。但是markdown字段中的图片路径不正确。
这是我在模板中拖放时图片的路径![](https://<domain>/<username>/image/upload/v1/media/markdownx/f44db8f1-f5b3-488b-b4f8-e8c730156746.jpg)
这是我在管理![](https://<domain>/<username>/image/upload/v1/media/markdownx/b41a8009-399d-4cc3-950a-7394536eece9.jpg)
拖放时图片的路径
但这是 Cloudinary 中的实际路径。
从模板保存的图像 https://<domain>/<username>/image/upload/v1595344310/media/markdownx/f44db8f1-f5b3-488b-b4f8-e8c730156746_nlek8c.jpg
管理员保存的图片 https://<domain>/<username>/image/upload/v1595344381/media/markdownx/b41a8009-399d-4cc3-950a-7394536eece9_fgpoob.jpg
现在从路径中我可以看到版本(我假设)部分不同,最后一部分在_
之后变得混乱。
但是我该如何解决这个问题?或者这根本不可能实现?
在 django-markdownx
和 dj3-cloudinary-storage
包的文档中找不到解决方案,因此任何建议/建议也非常有帮助。基本上,如果我可以将 Markdown 中的图像保存到 cloudinary 中,那将是一个胜利。
这里是必要的代码。
点文件
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
django = "*"
pillow = "*"
autopep8 = "*"
dj3-cloudinary-storage = "*"
django-markdownx = "*"
[requires]
python_version = "3.8"
settings.py(必要部分)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.forms', # for django-markdownx
# third party
'cloudinary_storage',
'cloudinary',
'markdownx',
# local
'pages.apps.PagesConfig',
]
# media
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
# cloudinary configs
CLOUDINARY_STORAGE =
'CLOUD_NAME': <user_name>,
'API_KEY': <public_key>,
'API_SECRET': <secret_key>,
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.MediaCloudinaryStorage'
urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('markdownx/', include('markdownx.urls')),
path('', include('pages.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
在我的pages
应用程序中,这些是代码。
models.py
from django.db import models
from django.urls import reverse
from markdownx.models import MarkdownxField
class Page(models.Model):
title = models.CharField(max_length=255)
description = MarkdownxField()
cover = models.ImageField(upload_to='covers/', blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("pages:detail", kwargs="pk": self.pk)
views.py
from django.views.generic import CreateView, DetailView
from .models import Page
class PageDetailView(DetailView):
model = Page
template_name = 'detail.html'
class PageCreateView(CreateView):
model = Page
template_name = 'new.html'
fields = ('title', 'description', 'cover',)
urls.py
from django.urls import path
from .views import PageCreateView, PageDetailView
app_name = 'pages'
urlpatterns = [
path('new/', PageCreateView.as_view(), name='new'),
path('<int:pk>/', PageDetailView.as_view(), name='detail')
]
提前谢谢你:)
【问题讨论】:
【参考方案1】:使用 cloudinary 时,您可以按原样或随机后缀上传带有随机字符的资产。
由于 dj3-cloudinary-storage
不受 cloudinary 官方支持,我不知道如何使用它。但如果您使用的是 cloudinary SDK,您可以这样做:
cloudinary.uploader.upload("https://res.cloudinary.com/demo/image/upload/v1561532539/sample.jpg", use_filename = True,unique_filename = False)
【讨论】:
谢谢!是的,我想过这样做,获取降价内容并获取图像,然后手动上传。我希望我是否可以跳过这个负担并使用一些包来解决它:((。如果不是这样,那就太不幸了。【参考方案2】:所以我喜欢使用降价和自定义图像上传到 Cloudinary 的解决方案。 我正在使用一个名为 django-markdown-editor(a.k.a. martor) 的包来实现这一点。这个包有一节如何使用自定义图像上传器而不是默认的 imgur 上传。
custom image uploader document
我的看起来像下面,
import cloudinary
class MarkdownImageUploader(View):
"""
custom image uploader for martor.
"""
def post(self, request, *args, **kwargs):
"""
called when images are uploaded to martor's markdown field.
validation is from martor's documentation.
it will upload images to cloudinary.
Note:
when there is '?' in the to be foldername the image upload will not work.
"""
folder_title = request.POST['title']
if not article_title:
return HttpResponse(_('Invalid request!'))
if not request.is_ajax():
return HttpResponse(_('Invalid request!'))
if 'markdown-image-upload' not in request.FILES:
return HttpResponse(_('Invalid request!'))
image = request.FILES['markdown-image-upload']
image_types = [
'image/png', 'image/jpg',
'image/jpeg', 'image/pjpeg', 'image/gif'
]
if image.content_type not in image_types:
# return error when the image type
# is not an expected type
data = json.dumps(
'status': 405,
'error': _('Bad image format.')
, cls=LazyEncoder)
return HttpResponse(
data, content_type='application/json', status=405)
if image.size > settings.MAX_IMAGE_UPLOAD_SIZE:
# return error when the image size
# is over the setted MAX_IMAGE_UPLOAD_SIZE
to_MB = settings.MAX_IMAGE_UPLOAD_SIZE / (1024 * 1024)
data = json.dumps(
'status': 405,
'error': _('Maximum image file is %(size) MB.') % 'size': to_MB
, cls=LazyEncoder)
return HttpResponse(
data, content_type='application/json', status=405)
# when the image is valid
# create new name for image
img_name = f'uuid.uuid4().hex[:10]-image.name.replace(" ", "-")'
# assign new name to the image that is being uploaded
image.name = img_name
# create folder path
img_folder = os.path.join(
settings.MEDIA_URL, f'folder_title/')
# save image to cloudinary
cloudinary_img = cloudinary.uploader.upload(
image, folder=img_folder, overwrite=True)
# get the saved image url from cloudinary response
cloudinary_img_url = cloudinary_img['secure_url']
# name json data to return to markdown
data = json.dumps(
'status': 200,
'link': cloudinary_img_url,
'name': image.name
)
return HttpResponse(data, content_type='application/json')
这与文档中的基本相同。只是取消了一些验证检查并更改了实际的保存部分。 Cloudinary 图片上传来自Cloudinary documents。唯一让我感到困惑的是,在云端文档中,它似乎传递了图像名称,但实际上我需要传递图像本身。
【讨论】:
以上是关于使用 markdown 和 cloudinary 的 django 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
未使用 Solidus 和 active_storage 上传到 Cloudinary 的图像
由于“cloudinary.uploader 未定义”错误,从 cloudinary 中删除媒体文件失败
我正在尝试使用 Cloudinary post API 上传图像而不使用 Cloudinary SDK
如何在 mongodb 和 mongoose 模型中使用 cloudinary