Evgenii Legotckoi
Evgenii LegotckoiҚыр. 11, 2023, 4:47 Т.Қ.

Django - қорғалған медиа мазмұны

Мен әзірлеп жатқан ресурстардың бірінде пайдаланушының осы медиа мазмұнға кіру құқығын тексере отырып, медиа-контентке қорғалған қолжетімділікті қосу қажеттілігі туындады. Қарапайым сөзбен айтқанда, пайдаланушы nginx статикалық мазмұн ретінде қызмет ететін фотосуретті көре алады.

Шын мәнінде, nginx және Django жағдайында бәрі бір қарағанда қарапайым болып көрінеді.

Мұны фотосуретті жүктеп салу және жүктеп салу мысалы арқылы қарастырайық.

Фотосуретпен жұмыс істеу алгоритмі

  • Фотосуретті арнайы қорғалған каталогқа жүктеп салу
  • Фотосуретке тікелей url арқылы немесе веб-сайт бетінде фотосуретті алу әрекеті (мысалы, img тегі)
  • Фотосурет рұқсаттарын тексеру
  • Nginx жүйесінде сервердегі ішкі қорғалған каталогқа қайта бағыттауды жасау
  • Фотосуретті қабылдау

Барлығы қарапайым болып көрінеді, бірақ енді бұл үшін не қажет екенін көрейік.

settings.py

Сайттың джанго конфигурация файлын баптайық. Әдетте, мультимедиалық мазмұнды жүктеп алу және оған nginx арқылы автоматты түрде қызмет көрсету үшін параметрлерде ұқсас нәрсе жазылған.

MEDIA_ROOT = BASE_DIR.parent / 'media'
MEDIA_URL = '/media/'

Дегенмен, бұл жолы біз әрқашан қорғалған деп атайтын арнайы қорғалған каталогты қолданамыз.

MEDIA_ROOT = BASE_DIR.parent / 'protected'
MEDIA_URL = '/media/'

Осылайша, біз сыртқы кеңістікте «медиа» бар, ал сервердің қараңғы залдарында «қорғалған» дейміз.

Мұндай код келесі каталог құрылымына сәйкес келуі мүмкін.

  • /home/www/django_project_root_folder - бұл жоба, статикалық және бал каталогтары, сондай-ақ виртуалды орта орналасқан негізгі каталог.
  • /home/www/django_project_root_folder/protected - қорғалған медиа каталогы
  • /home/www/django_project_root_folder/static - статикалық мазмұны бар каталог
  • /home/www/django_project_root_folder/django_project - сіздің джанго қолданбаңыз
  • /home/www/django_project_root_folder/python_venv - виртуалды орта

Маған қазір бұл құрылым ұнайды, өйткені егер python нұсқасы өзгерсе, яғни виртуалды орта жаңартылса, сіз жай ғана жаңа ортаны инициализациялауға және конфигурациядағы бірнеше жолды өзгертуге болады, осылайша сайт қолданбасы жаңа виртуалды ортадан іске қосылады. . Бұл жағдайда жоба репозиторийіне де, статикалық файлдарға да, медиа мазмұнына да әсер етпейді.

nginx конфигурациясы

Мен қорғалған каталогқа nginx қатынасын орнатуға тікелей жауапты конфигурацияның шағын бөлігін беремін.

 server {

     # Other code

     location /protected/ {
        internal;
        root /home/www/django_project_root_folder/;
        expires 30d;
    }
}

Бұл код арқылы біз қорғалған каталогтың қай жерде орналасқанын және оның ішкі екенін ғана көрсетеміз, яғни пайдаланушы оның мазмұнын арнайы рұқсатсыз жай ғана қабылдамайды.

Фотосуреттерді жүктеп салу

Фотосуреттермен жұмыс істеу үшін мен қазір бұл деректер үлгісін қолданамын, әрине, нақты жоба үшін модификациялармен, бірақ негізі бірдей

# -*- coding: utf-8 -*-

import os
import uuid

from django.contrib.gis.db import models
from django.db.models.signals import post_delete
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _

from photo.fields import WEBPField
from photo.managers import PhotoManager


def image_folder(instance, filename):
    return 'photos/{}.webp'.format(uuid.uuid4().hex)


class Photo(models.Model):
    class Meta:
        verbose_name = _('Photo')
        verbose_name_plural = _('Photos')

    created_at = models.DateTimeField(verbose_name=_('Created at'), auto_now_add=True)
    updated_at = models.DateTimeField(verbose_name=_('Updated at'), auto_now=True)
    height = models.IntegerField(verbose_name=_('Height'), default=0, blank=True, null=True)
    width = models.IntegerField(verbose_name=_('Width'), default=0, blank=True, null=True)
    image = WEBPField(
        verbose_name=_('Image'),
        upload_to=image_folder,
        height_field='height',
        width_field='width',
    )

    def filename(self):
        return os.path.basename(self.image.name)


@receiver(post_delete, sender=Photo)
def auto_delete_image_on_delete(sender, instance, **kwargs):
    if instance.image:
        if os.path.isfile(instance.image.path):
            os.remove(instance.image.path)

Мұнда арнайы өріс WEBPField пайдаланылады, ол туралы мен айтқанмын. Бұл кескінді жылдам webp пішіміне түрлендіретін өріс. Сондай-ақ серверден фотосуреттерді автоматты түрде жою коды бар. Бірақ бұл ең маңызды нәрсе емес.

Ең бастысы - бұл функция

def image_folder(instance, filename):
    return 'photos/{}.webp'.format(uuid.uuid4().hex)

Бұл функция файл атауын жасайды және қорғалған каталогқа қатысты файлды серверде сақтау орнын көрсетеді.

Нәтижесінде фотосурет келесі жолда сақталады

/home/www/django_project_root_folder/protected/photos/0aec484a6ff246d7ad5eb1b06c0a698e.webp

Бұл жағдайда үлгідегі img тегінің коды келесідей болады:

<img src="{{ photo.image.url }}"/>

Ал нәтиже келесідей болады

<img src="/media/photos/0aec484a6ff246d7ad5eb1b06c0a698e.webp"/>

urls.py

Мазмұнға қол жеткізу үшін url менеджерін көрсетуден бастаймын

# -*- coding: utf-8 -*-

from django.urls import path

from photo.views import photo_access

urlpatterns = [
    path('media/photos/<str:path>', photo_access, name='photo'),
]

Көріп отырғаныңыздай, мұнда img тегінің нәтижесіне сәйкес келетін url бар.

Фотосуретке қол жеткізу функциясы

Енді ең қызығы - қорғалған мазмұнға қол жеткізу қалай жүзеге асырылады

# -*- coding: utf-8 -*-

from django.http import HttpResponse, HttpResponseForbidden

from photo.models import Photo
from utils.shortcuts import get_object_or_none


def photo_access(request, path):
    def create_x_accel_redirect(path):
        response = HttpResponse()
        # Content-type will be detected by nginx
        del response['Content-Type']
        response['X-Accel-Redirect'] = '/protected/photos/' + path
        return response

    photo = get_object_or_none(Photo, image='photos/' + path)
    if photo is None:
        return HttpResponseForbidden('Not authorized to access this media.')

    # Some another check code
    if condition is True:
        return create_x_accel_redirect(path)

    if request.user.is_authenticated and request.user.is_staff:
        return create_x_accel_redirect(path)

    return HttpResponseForbidden('Not authorized to access this media.')

Бұл функцияда біз пайдаланушының ресурс әкімшілігінің уәкілетті өкілі екенін және фотообъектінің бар-жоғын тексереміз. Сондай-ақ, сіз өзіңізге ұнайтын кез келген басқа шарттарды қоса аласыз.

Егер олар орындалса, create_x_accel_redirect функциясын пайдаланып, nginx ішіндегі сұрауды кескінге қайта бағыттайтын директиваны қосамыз.

Яғни, /media/photos/0aec484a6ff246d7ad5eb1b06c0a698e.webp орнына /protected/photos/0aec484a6ff246d7ad5eb1b06c0a698e.webp және direct-cc-redirect.X сұрауын қайта бағыттау** ауыстырамыз.
Осылайша, nginx қорғалған каталогтағы мазмұнды медиа url арқылы қызмет етеді.

X-Accel-Redirect директивасы туралы толығырақ ақпаратты ресми nginx wiki сайтынан табуға болады

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Г

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 10:50 Т.Ж.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 8:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 3:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 4, 2024, 10:50 Т.Қ.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 12:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 1:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 24, 2024, 10 Т.Қ.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 2:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 11:07 Т.Ж.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Бізді әлеуметтік желілерде бақылаңыз