Django представление в PNG

Я пишу django webapp, и часть его должна генерировать представление и конвертировать его в png изображение. (Любые идеи, кроме нижеприведенных, будут оценены по достоинству). Я просмотрел несколько инструментов для преобразования «html в png», но в основном есть проблемы с {%static файлами и шаблонами. Другой подход заключается в рендеринге страницы с использованием шаблонов django в браузере, и сделать скриншот. Это можно сделать с помощью «chromedriver» + selenium. Я смог сделать это на своей локальной ubuntu. Но на production - все, что у меня есть, это удаленный (ssh) доступ к некоторому linux bash, где размещено мое приложение. Я создал venv, установил selenium и (chromedriver-py или chromedriver-binary). Что касается второго варианта - он вроде бы уже близок к тому, чтобы начать работать, но я получаю сообщение об ошибке: SessionNotCreatedException . Сообщение: сессия не создана: вероятно, каталог данных пользователя уже используется, пожалуйста, укажите уникальное значение для аргумента --user-data-dir или не используйте --user-data-dir

Stackoverflow говорит, что я должен каким-то образом указать путь к пользовательскому dir моей установки chrome, но есть ли какая-либо установка chrome в этом моем консольном bash?

Есть идеи, как двигаться дальше? или любые другие идеи, как это сделать? Мой код:

import chromedriver_binary   


def render_to_png(request ):  
      
     
    chrome_options = webdriver.ChromeOptions() 
    chrome_options.add_argument("--headless")  # Run in headless mode (no GUI)
    driver = webdriver.Chrome( options=chrome_options) 
    driver.get("someurl.com") 
    driver.save_screenshot("x.png")
     
    driver.quit()
    return HttpResponse(status=200)

Вот развернутый ответ, который может помочь:

Для использования html2canvas в django вам может понадобиться ссылка cdn: https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js

Сценарий на стороне клиента

<script>
    function captureAndUpload() {
        const element = document.getElementById('capture-area'); // replace with your html element id or = document.body for whole page
        
        html2canvas(element).then(canvas => {
            canvas.toBlob(blob => {
                const formData = new FormData();
                formData.append('image', blob, 'screenshot.png');

                fetch('/upload-image/', { // replace with djgango url
                    method: 'POST',
                    body: formData,
                    headers: {
                        'X-CSRFToken': getCSRFToken() // include CSRF token if CSRF enabled
                    }
                })
                .then(response => response.json())
                .then(data => {
                    console.log('Upload successful:', data);
                })
                .catch(error => {
                    console.error('Error uploading image:', error);
                });
            }, 'image/png');
        });
    }

    // function to get CSRF token
    function getCSRFToken() {
        const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
        return csrfToken;
    }
</script>

Кнопка

<button onclick="captureAndUpload()">Capture and Upload</button>

Django логика на стороне сервера

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import default_storage

@csrf_exempt  # Use this only if CSRF tokens are not included
def upload_image(request):
    if request.method == 'POST' and 'image' in request.FILES:
        image = request.FILES['image']
        file_path = default_storage.save(f'uploads/{image.name}', image)
        return JsonResponse({'message': 'Image uploaded successfully', 'file_path': file_path})
    return JsonResponse({'error': 'Invalid request'}, status=400)

Urls.py

...

urlpatterns = [
    path('upload-image/', upload_image, name='upload-image'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Еще одна вещь, которую нужно добавить в settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
Вернуться на верх