使用markdown和cloudinary的Django应用程序

2024-05-23 20:16:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试同时使用django-markdownxdj3-cloudinary-storage创建django应用程序

所以django-markdownx的一个特性是,您可以在标记字段中拖放图像,它会保存该图像并返回图像的路径。在当地,这一切都很好。将图像拖放到makrdown字段,并按预期将其保存到/media/markdownx/路径,标记字段中的图像路径正确。但是,在与Cloudinary连接后,这无法正常工作。拖放图像后,它会将图像保存到Cloudinary。但是标记字段中的图像路径不正确

这是在模板中拖放时图像的路径![](https://<domain>/<username>/image/upload/v1/media/markdownx/f44db8f1-f5b3-488b-b4f8-e8c730156746.jpg)

这是我在admin![](https://<domain>/<username>/image/upload/v1/media/markdownx/b41a8009-399d-4cc3-950a-7394536eece9.jpg)中拖放图像时的路径

然而,这是Cloudinary中的实际路径

从模板保存的图像

从管理员保存的图像

现在从路径中我可以看到版本(我假设)部分不同,最后一部分在_之后混乱

但是我怎么才能解决这个问题呢?还是这根本不可能实现?
无法在django-markdownxdj3-cloudinary-storage包的文档中找到解决方案,因此任何建议/建议都非常有用。基本上,如果我能将图像以降价方式保存到cloudinary,那将是一场胜利

以下是必要的代码

Pipfile

[[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"

设置.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'

url.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应用程序中,这些是代码

型号.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',)

url.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')
]

提前感谢:)


Tags: pathdjangonamefrom图像import路径admin
2条回答

因此,我喜欢使用降价和自定义图像上传到Cloudinary的解决方案。 我正在使用一个名为django-markdown-editor(也称为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。唯一让我困惑的是在cloudinary文档中,它似乎传递了图像名称,但实际上我需要传递图像本身

使用cloudinary时,您可以按原样或随机后缀上传带有随机字符的资产

由于cloudinary没有正式支持dj3-cloudinary-storage,我不知道如何使用它。但如果您使用的是cloudinary SDK,则可以执行以下操作:

cloudinary.uploader.upload("https://res.cloudinary.com/demo/image/upload/v1561532539/sample.jpg", use_filename = True,unique_filename = False)

相关问题 更多 >