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 есть "подозрительные" одинарные или обратные косые черты.