Django/Python - Как присвоить переменной путь к файлу независимым от платформы способом?

У меня есть проект Django, в котором одна из файловых переменных .env будет представлять абсолютный путь к файлу. Например,

DEBUG=True
SECRET_KEY='blah_blah_blah'
MY_STORAGE_PATH = 'D:\\files\\for\\my\\project'

Очевидно, что вышеописанный способ будет отлично работать на машине с Windows и диском D:, но он не подойдет, если диска D: нет или если на машине используется другая ОС.

Теперь я могу придумать любое количество функциональных способов предоставить эту .env строку независимым от платформы способом, а затем использовать манипуляции со строками и методы os.path для сборки фактического пути. Я мог бы разделить путь "диск &" отдельно, используя "нейтральный" разделитель путей по своему усмотрению:

MY_STORAGE_DRIVE_FOR_WIN = 'D:'
MY_STORAGE_PATH  = '|files|for|my|project'

... Я могу предоставить конфигурацию в виде списка, преобразовать ее в реальный список, а затем передать в os.path.join():

MY_STORAGE_PATH_ELEMENTS  = '["files","for","my","project"]'

... и так далее, и так далее.

Но прежде чем я пойду по этому пути, я хотел бы узнать: существует ли какая-то общепринятая конвенция для такого рода случаев использования? (Наверняка это не первый случай, когда кому-то понадобилось предоставить значение .env для представления платформонезависимого пути?)

Эти строки определяют в вашем settings.py файле путь к файлам, все файлы хранятся в вашей папке media, а папка media находится в вашей project directory. Вы можете изменить свой путь BASE_DIR или использовать его как есть.

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent    

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

Эти строки вы можете добавить в свой основной файл urls.

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # your urls comes here...
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Вот как вы можете использовать его в своем проекте.

def upload_to(instance, filename):
    return '/'.join([str(instance), filename])

class Student(AbstractUser, TimeStampedModel):
    profile_image = models.ImageField(upload_to='StudentProfileImage/', null=True, blank=True)
    background_image = models.ImageField(upload_to='StudentBackground/', null=True, blank=True)

Thess - это имена папок StudentProfileImage StudentBackground, которые создаются в папке media автоматически.

Я бы использовал разделитель, который не будет частью нормального файлового пути ни на одной платформе. Возможно, '//'. Учитывая ENVVAR = "D://first//second//file.name":

pathname = os.path.join( *ENVVAR.split('//'))

os.path.join вставит любой разделитель, необходимый для платформы, на которой он запущен.

Если вы хотите защищать код, то также выведите предупреждение, если в ENVVAR есть "подозрительные" одинарные или обратные косые черты.

Вернуться на верх