Django просмотр списка файлов директории здесь не разрешен
приложение Django, над которым я работаю, имеет Event модель. Ан Event может иметь связанные фотографии, статические html-файлы и pdf-файлы.
Я хотел бы разрешить доверенным пользователям загружать эти файлы, но я опасаюсь о безопасности, особенно прочитав следующее в документах Django (ссылка).
обратите внимание, что когда вы имеете дело с загруженные файлы, вы должны внимательно внимание, куда вы загружаете их и какой тип файлов они являются, чтобы избежать дыр в безопасности. Проверить все загруженные файлы, так что вы уверены, что файлы-это то, что вы думаете. Для например, если вы слепо позволяете кому-то загрузка файлов без проверки в a каталог это в веб корень документа сервера, затем кто-то может загрузить скрипт CGI или PHP и выполните этот скрипт, посетив его URL на вашем сайте. Не позволяй этого.
Как я могу проверить различные типы файлов? Мне было бы интересно услышать чей-либо опыт работы с такого рода вещами или ссылки для дальнейшего чтения. У меня есть чувство, что html-файлы могут быть слишком рискованными, и в этом случае я ограничу права на загрузку администратору.
все ответы сосредоточены на проверке файлов. Это практически невозможно.
разработчики Django не просят вас проверить, могут ли файлы быть выполнены as файлы cgi. Они просто говорят вам, чтобы вы не помещали их в место, где они будет быть казнен.
вы должны поместить все вещи Django в специально каталог Django. Этот каталог кода Django не должен содержать статического содержимого. не помещайте пользовательские файлы в Хранилище исходного кода в Django.
Apache2 может быть настроен для запуска любых файлов в . не помещайте пользовательские файлы в /cgi-bin/ или /usr/local/apache2/cgi-bin/ папки.
Apache2 может быть установлен в файлы CGI сервера, в зависимости от AddHandler cgi-script настройки. не позволяйте пользователям отправлять файлы с расширениями, такими как .cgi или .pl .
тем не менее, вам нужно дезинфицировать пользовательские файлы, чтобы они были безопасны для работы на машинах других клиентов. представленный HTML небезопасен для других пользователей. это не повредит вашему серверу. Ваш сервер просто выплюнет его в ответ на любой запрос. Получите дезинфицирующее средство HTML.
и SVG может быть небезопасным. У него были жуки в прошлом. SVG-это XML-документ с javascript, поэтому он может быть вредоносным.
в формате PDF . хитрый. Вы можете преобразовать его в изображение (если вам действительно нужно) или предоставить предварительный просмотр изображения (и позволить пользователям загружать на свой страх и риск), но это будет больно для людей, пытающихся его использовать.
рассмотрим белый список файлов, которые в порядке. вирус, встроенный в файл gif, jpeg или png, будет выглядеть как поврежденное изображение (или не будет отображаться). Если вы хотите быть параноиком, преобразуйте их все в стандартный формат с помощью PIL (Эй, вы также можете проверьте размеры). Санированный HTML должен быть в порядке (удаление тегов скриптов не является ракетостроением). Если дезинфекция всасывает циклы (или вы просто осторожны), вы можете поместить его на отдельный сервер, я думаю.
для изображений вы можете просто использовать Библиотека Изображений Python (PIL).
Если файл не является изображением, будет выброшено исключение. Я довольно новичок в Python / Django, поэтому у кого-то еще может быть лучший способ проверки изображений.
первое, что вы хотите сделать с загруженным контентом, это сохранить его в каталоге, который непосредственно не доступен для загрузки. Если ваше приложение существует в ~/www/ рассмотрите возможность ввода данных в ' ~ / data/'.
во-вторых, вам нужно определить, какой файл загрузил пользователь, а затем создать правила для каждого типа файла.
вы не можете доверять файлу на основе расширения, поэтому используйте что-то вроде FileInfo на. Затем для каждого типа mime, создать валидатор. ImageMagick может проверять файлы изображений. Для повышения безопасности вам может потребоваться запустить антивирусный сканер над файлами, такими как pdf и flash-файлы. Для html вы можете рассмотреть ограничение на подмножество тегов.
Я не могу найти эквивалент Python Fileinfo модуль, хотя всегда можно exec /usr/bin/file -i . Большинство систем, которые позволяют загружать, затем создают имя или идентификатор контента. Затем они используют mod_rewrite для анализа URL-адреса и поиска содержимого на диске. Как только содержание найден, он возвращается пользователю с помощью sendfile или чего-то подобного. Например, пока содержимое не будет одобрено, просматривать его может только пользователь, который его загрузил.
Это немного специфичные для вашей среды хостинга, но вот что я делаю:
обслуживать весь пользовательский загруженный контент с Nginx вместо apache и обслуживать его как статический контент (он не будет запускать ни php, ни cgi, даже если пользователи загружают его)
"доверенные пользователи" - это субъективный термин. Это люди, которых вы знаете лично или только тот, кто создал учетную запись в вашем приложении? Не предоставляйте доступ к вашей файловой системе людям, которых вы не знаете лично.
предоставление возможности кому-то загрузить файл в любом случае немного опасно, и я думаю, что этого следует избегать. На прошлой неделе я столкнулся с аналогичной проблемой с автоматической загрузкой html-кода, и я решил сохранить его в базе данных. Я думаю, что в в большинстве случаев можно использовать базу данных, а не файловую систему.
одна из проблем с проверкой заключается в том, что вам придется написать новый валидатор для любого типа файлов. Это может быть ограничение в будущем и быть в некоторых случаях.
В этом руководстве мы рассмотрим основные ошибки Django-разработчиков и узнаем, как их избежать. Статья может быть полезна даже опытным разработчикам, потому что и они совершают такие ошибки, как поддержка неподъёмно больших настроек или конфликтов имён в статических ресурсах.
Django — бесплатный сетевой open source Python-фреймворк, помогающий решать распространённые в разработке проблемы. Он позволяет создавать гибкие, хорошо структурированные приложения. В Django уже из коробки есть много современных возможностей. Например, для меня такие фичи, как Admin, инструмент Object Relational Mapping (ORM), Routing и Templating, делают Django первым кандидатом при выборе инструментария для разработки. Создание приложения требует много сил, и, наслаждаясь своим делом, как и любой разработчик, я хочу тратить как можно меньше времени на рутинные задачи. Django сильно в этом помогает, не заставляя жертвовать гибкостью приложения.
Киллер-фича Django — мощный конфигурируемый админский интерфейс, который автоматически (автомагически?) генерируется на основе схемы вашей модели и моделей админки. Чувствуешь себя прямо-таки волшебником. С помощью интерфейса Admin пользователь может конфигурировать много вещей, в их числе — список управления доступом (access control list, ACL), разрешения и действия на уровне строк (row-level), фильтры, порядки сортировки (orders), виджеты, формы, дополнительные URL-хелперы и многое другое. Я считаю, что админка нужна каждому приложению. Это лишь вопрос времени, когда такая панель понадобится вашему основному приложению. В Django она создаётся быстро и удобно.
Также в Django есть мощная ORM, из коробки работающая со всеми главными базами данных. Она «ленива»: в отличие от других ORM, обращается к БД только по мере необходимости. В ней есть поддержка основных SQL-инструкций (и функций), которые вы можете использовать из своего исходного Python-кода наряду со всеми остальными возможностями языка.
В Django очень гибкий и мощный шаблонизатор (templating engine). Доступны многие стандартные фильтры и метки (tags), также можно создавать свои собственные. Django поддерживает другие движки как собственные шаблоны, предоставляет API для лёгкой интеграции с другими движками посредством стандартных shortcut-функций для обработки шаблонов.
Фреймворк имеет и много других важных возможностей вроде URL-роутера, который парсит входящие запросы и генерирует новые URL на основе схемы роутинга. В целом Django приятен в работе, и, когда вам понадобится помощь, просто почитайте документацию.
Ошибка № 1. Использование для проектных зависимостей глобального окружения Python
Не используйте глобальное окружение Python для зависимостей вашего проекта, потому что это может привести к возникновению конфликтов зависимостей. Python не умеет работать с несколькими версиями пакетов одновременно. Это станет проблемой, если разным проектам нужны разные, несовместимые версии одного пакета.
Обычно такую ошибку допускают новички в Python- и Django-разработке, не знающие об особенностях изоляции окружения Python.
Есть много способов изолировать окружение, наиболее часто встречаются такие:
- virtualenv: пакет Python, генерирующий папку с окружением. Содержит скрипт для (де)активации окружения и управления установленными в нём пакетами. Это мой любимый и самый простой метод. Обычно я создаю окружение поближе к папке проекта.
- virtualenvwrapper: пакет Python, глобально устанавливающий набор инструментов для создания/удаления/активации и т. д. виртуальных окружений и предоставляющий доступ к этому набору. Все окружения хранятся в одной папке (её можно переписать с помощью переменной WORKON_HOME). Я не вижу преимуществ в использовании virtualenvwrapper вместо virtualenv .
- Виртуальные машины: нет лучшей изоляции, чем целая виртуальная машина, выделенная под ваше приложение. Есть масса доступных инструментов, например VirtualBox (бесплатный), VMware, Parallels и Proxmox (мой фаворит, есть бесплатная версия). В сочетании с инструментом автоматизации виртуальных машин вроде Vagrant это может оказаться очень мощным решением.
- Контейнеры: в последние годы я почти в каждом проекте использую Docker, особенно в новых проектах, начинаемых с нуля. Docker — невероятный инструмент с множеством возможностей. Для его автоматизации доступна куча сторонних инструментов. В Docker есть кеширование уровней (layer caching), позволяющее крайне быстро пересоздавать контейнеры. В них я использую глобальное окружение Python, потому что каждый контейнер имеет собственную файловую систему и проекты изолируются на высоком уровне. Docker позволяет новым членам команды быстрее начинать работу над проектом, особенно если у них есть опыт работы с этой технологией.
Ошибка № 8. Использование в production STATICFILES_STORAGE по умолчанию и загрузчиков Django-шаблонов
Давайте поговорим об управлении ресурсами (asset) production-окружения. Мы можем обеспечить наилучший UX, если воспользуемся политикой «у ресурсов не истекает срок действия» (assets never expire) (подробнее о ней можно почитать здесь). Это означает, что все наши статичные файлы должны быть закешированы браузерами на недели, месяцы или даже годы. Иными словами, пользователи должны лишь единожды скачивать ресурсы!
Классная идея, и её можно реализовать всего в несколько строк в nginx-конфигурации для нашей папки со статичными файлами. Но что насчёт проверки актуальности кеша? Если пользователь лишь один раз скачивает наш ресурс, то что делать в том случае, если вы обновите логотип, шрифты, JavaScript или цвет текста в меню? Для решения этой задачи вам нужно при каждом развёртывании генерировать уникальные URL’ы и имена для каждого статичного файла!
Для этого можно использовать ManifestStaticFilesStorage в качестве STATICFILES_STORAGE (будьте осторожны, хеширование включается только в режиме DEBUG=false ) и выполнить команду collectstatic . Это приведёт к снижению количества запросов ресурсов у вашего production-сайта и сделает его отрисовку гораздо быстрее.
Клёвая фича Django — закешированный загрузчик шаблона. Он не перезагружается и парсит файлы шаблона при каждой его отрисовке. Парсинг шаблона — очень дорогая операция, она требует много вычислительных ресурсов. По умолчанию Django-шаблоны парсятся при каждом запросе, а это плохо, особенно в production, где за короткий промежуток времени могут обрабатываться тысячи запросов.
В разделе конфигурации cached.Loader можно найти хороший пример и подробности решения проблемы. Не используйте загрузчик в режиме разработки, потому что он не перезагружает отпарсенные шаблоны из файловой системы. Вам понадобится перезапускать свой проект, используя python manage.py startapp , при каждом изменении шаблона. При разработке это может раздражать, зато идеально для production-окружения.
Ошибка № 10. Велосипедостроение
Для Django и Python есть тысячи готовых решений. Обратитесь к поисковикам, прежде чем писать что-то, что вовсе не уникально. Вероятно, уже есть подходящее решение.
Не надо усложнять. Сначала — гуглим! Установите найденный качественный пакет, сконфигурируйте, расширьте и интегрируйте в свой проект. И если есть возможность, внесите свой вклад в open source.
Вот вам для начала список моих собственных пакетов для Django:
-
: с помощью макросов облегчает написание (и чтение) URL-паттернов в Django-приложениях. : маленький миксин, помогает легко стандартизировать имена ваших CBV-шаблонов. : позволяет распределить Django-настройки по нескольким файлам и директориям. Легко переопределяет и модифицирует настройки. Использует подстановки (wildcards) в путях файлов и помечает файлы настроек как опциональные.
Don’t repeat yourself (DRY)!
Я сторонник DRY-концепции, поэтому создал Django skeleton — удобный инструмент с рядом приятных функций уже из коробки:
- Docker-образы для разработки/production, управляемые docker-compose, что позволяет легко оркестрировать списком контейнеров.
- Простой Fabric-скрипт для развёртывания в production.
- Конфигурация для пакета Django Split Settings с настройками базы и локальных источников.
- Интегрированный в проект Webpack — при выполнении команды collectstatic Django соберёт только папку dist.
- Сконфигурированы все основные Django-настройки и фичи вроде кешируемых в production Django-шаблонов, хешированных статичных файлов, интегрированного тулбара для отладки, журналирования и т. д.
Это готовый к использованию Django-скелет для вашего следующего проекта, создаваемого с нуля. Надеюсь, он сэкономит вам кучу времени. Webpack имеет минимальную базовую конфигурацию, но также в него с помощью SASS установлены заранее сконфигурированные для обработки файлы .scss.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Сами по себе аутентификация или идентификация обычно недостаточны для получения доступа к информации или коду. Для этого объект, запрашивающий доступ, должен иметь авторизацию.
— Apple Developer Documentation
Вместе с аутентификацией и регулированием разрешения определяют, должен ли запрос быть предоставлен или запрещен доступ.
Разрешения используются для предоставления или запрета доступа разным классам пользователей к разным частям API.
Самый простой стиль разрешения - разрешить доступ любому аутентифицированному пользователю и запретить доступ любому неаутентифицированному пользователю. Это соответствует классу IsAuthenticated в REST framework.
Чуть менее строгий стиль разрешений - разрешить полный доступ аутентифицированным пользователям, но разрешить доступ только для чтения неаутентифицированным пользователям. Это соответствует классу IsAuthenticatedOrReadOnly в REST framework.
Как определяются разрешения
Разрешения в REST framework всегда определяются как список классов разрешений.
Перед запуском основной части представления проверяется каждое разрешение в списке. Если какая-либо проверка разрешений не удалась, будет возбуждено исключение exceptions.PermissionDenied или exceptions.NotAuthenticated , и основная часть представления не будет запущена.
Если проверка разрешений завершится неудачно, будет возвращен ответ 403 Forbidden или 401 Unauthorized в соответствии со следующими правилами:
Разрешения на уровне объекта
Разрешения REST framework также поддерживают разрешение на уровне объекта. Разрешения на уровне объекта используются для определения того, следует ли разрешить пользователю действовать с конкретным объектом, который обычно является экземпляром модели.
Разрешения на уровне объекта выполняются общими представлениями инфраструктуры REST при вызове .get_object() . Как и в случае с разрешениями уровня представления, исключение exceptions.PermissionDenied будет вызвано, если пользователю не разрешено действовать с данным объектом.
Это либо вызовет исключение PermissionDenied , либо NotAuthenticated , либо просто вернется, если представление имеет соответствующие разрешения.
Примечание: За исключением DjangoObjectPermissions , предоставленные классы разрешений в rest_framework.permissions не реализуют методы, необходимые для проверки разрешений объекта.
Если вы хотите использовать предоставленные классы разрешений для проверки прав доступа к объектам, вы должны создать подклассы и реализовать метод has_object_permission() , описанный в разделе Custom permissions (ниже).
Ограничения разрешений на уровне объекта
По соображениям производительности общие представления не будут автоматически применять разрешения уровня объекта к каждому экземпляру в наборе запросов при возврате списка объектов.
Часто, когда вы используете разрешения на уровне объекта, вам также нужно фильтровать набор запросов соответствующим образом, чтобы гарантировать, что пользователи видят только те экземпляры, которые им разрешено просматривать.
Установка политики разрешений
Политика разрешений по умолчанию может быть установлена глобально с помощью параметра DEFAULT_PERMISSION_CLASSES . Например.
Если не указано, по умолчанию этот параметр разрешает неограниченный доступ:
Вы также можете установить политику аутентификации для каждого представления или набора представлений, используя представления на основе классов APIView .
Или, если вы используете декоратор @api_view с представлениями на основе функций.
Примечание: когда вы устанавливаете новые классы разрешений через атрибут класса или декораторы, вы говорите представлению игнорировать список по умолчанию, установленный в файле settings.py.
При условии, что они наследуются от rest_framework.permissions.BasePermission , разрешения могут быть составлены с использованием стандартных побитовых операторов Python. Например, IsAuthenticatedOrReadOnly можно записать:
Примечание: поддерживает & (and) , | (или) и ~ (не) .
Справочник по API
Класс разрешений AllowAny разрешит неограниченный доступ независимо от того, был ли запрос аутентифицирован или не аутентифицирован.
Это разрешение не является строго обязательным, поскольку вы можете достичь того же результата, используя пустой список или кортеж для настройки разрешений, но вы можете найти полезным указать этот класс, потому что он делает намерение явным.
Класс разрешений IsAuthenticated откажет в разрешении любому неаутентифицированному пользователю и разрешит разрешение в противном случае.
Класс разрешений IsAdminUser будет отказывать в разрешении любому пользователю, если только user.is_staff не равен True , и в этом случае разрешение будет разрешено.
Это разрешение подходит, если вы хотите, чтобы ваш API был доступен только подмножеству доверенных администраторов.
IsAuthenticatedOrReadOnly позволит аутентифицированным пользователям выполнять любой запрос. Запросы для неавторизованных пользователей будут разрешены только в том случае, если метод запроса является одним из «безопасных» методов: GET , HEAD или OPTIONS .
Это разрешение подходит, если вы хотите, чтобы ваш API разрешал чтение анонимным пользователям и разрешал запись только аутентифицированным пользователям.
Этот класс разрешений связан со стандартным Django django.contrib.auth разрешения модели. Это разрешение должно применяться только к представлениям, у которых установлено свойство .queryset . Авторизация будет предоставлена только в том случае, если пользователь аутентифицирован и ему назначены соответствующие разрешения модели.
- Запросы POST требуют, чтобы у пользователя было право add на модель.
- Запросы PUT и PATCH требуют, чтобы у пользователя было право change модели.
- Запросы DELETE требуют, чтобы у пользователя было право delete модели.
Поведение по умолчанию также можно переопределить для поддержки разрешений настраиваемой модели. Например, вы можете захотеть включить разрешение модели view для запросов GET .
Чтобы использовать разрешения пользовательской модели, переопределите DjangoModelPermissions и установите свойство .perms_map . За подробностями обращайтесь к исходному коду.
Использование с представлениями, не содержащими атрибут queryset .
Если вы используете это разрешение с представлением, в котором используется переопределенный метод get_queryset() , то в представлении может не быть атрибута queryset . В этом случае мы предлагаем также пометить представление контрольным набором запросов, чтобы этот класс мог определить необходимые разрешения. Например:
Подобно DjangoModelPermissions , но также позволяет неаутентифицированным пользователям иметь доступ только для чтения к API.
Этот класс разрешений связан со стандартной структурой разрешений объектов Django, которая разрешает разрешения для каждого объекта в моделях. Чтобы использовать этот класс разрешений, вам также необходимо добавить серверную часть разрешений, которая поддерживает разрешения на уровне объектов, например django-guardian.
Как и в случае DjangoModelPermissions , это разрешение должно применяться только к представлениям, имеющим свойство .queryset или метод .get_queryset() . Авторизация будет предоставлена только в том случае, если пользователь аутентифицирован и имеет соответствующие разрешения для каждого объекта и соответствующие разрешения модели.
- Запросы POST требуют, чтобы у пользователя было право add на объект модели.
- Запросы PUT и PATCH требуют, чтобы у пользователя было право change на объект модели.
- Запросы DELETE требуют, чтобы у пользователя было право delete на объект модели.
Обратите внимание, что DjangoObjectPermissions не требует пакета django-guardian и должен поддерживать другие серверные части объектного уровня одинаково хорошо.
Как и в случае с DjangoModelPermissions , вы можете использовать пользовательские разрешения модели, переопределив DjangoObjectPermissions и установив свойство .perms_map . За подробностями обращайтесь к исходному коду.
Примечание: Если вам нужны разрешения view на уровне объекта для запросов GET , HEAD и OPTIONS и вы используете django-guardian для своей серверной части разрешений на уровне объекта, вам следует рассмотреть возможность использования Класс DjangoObjectPermissionsFilter , предоставляемый пакетом djangorestframework-guardian . Это гарантирует, что конечные точки списка возвращают только результаты, включая объекты, для которых у пользователя есть соответствующие разрешения на просмотр.
Чтобы реализовать настраиваемое разрешение, переопределите BasePermission и реализуйте один или оба из следующих методов:
- .has_permission(self, request, view)
- .has_object_permission(self, request, view, obj)
Методы должны возвращать True , если запросу должен быть предоставлен доступ, и False в противном случае.
Если вам нужно проверить, является ли запрос операцией чтения или записи, вы должны проверить метод запроса на соответствие константе SAFE_METHODS , которая представляет собой кортеж, содержащий 'GET' , 'OPTIONS' и 'HEAD' . Например:
Ниже приведен пример класса разрешений, который проверяет IP-адрес входящего запроса по списку блокировки и отклоняет запрос, если IP-адрес был заблокирован.
Помимо глобальных разрешений, которые выполняются для всех входящих запросов, вы также можете создавать разрешения на уровне объекта, которые выполняются только для операций, влияющих на конкретный экземпляр объекта. Например:
Также обратите внимание, что общие представления будут проверять разрешения на уровне объекта только для представлений, которые получают один экземпляр модели. Если вам требуется фильтрация представлений списков на уровне объекта, вам необходимо отфильтровать набор запросов отдельно. см. Документацию по фильтрации для получения более подробной информации.
Также доступны следующие сторонние пакеты.
DRF - Access policy
Пакет Django REST - Access policy предоставляет способ определения сложных правил доступа в классах декларативных политик, которые прикреплены к наборам представлений или представлениям на основе функций. Политики определены в JSON в формате, аналогичном политикам AWS Identity & Access Management .
Пакет [Composed Permissions][formed-permissions] предоставляет простой способ определения сложных и многоуровневых (с логическими операторами) объектов разрешений с использованием небольших и повторно используемых компонентов.
Пакет REST Condition - еще одно расширение для создания сложных разрешений простым и удобным способом. Расширение позволяет комбинировать разрешения с логическими операторами.
DRY Rest Permissions
Пакет DRY Rest Permissions предоставляет возможность определять различные разрешения для отдельных действий по умолчанию и настраиваемых действий. Этот пакет предназначен для приложений с разрешениями, производными от отношений, определенных в модели данных приложения. Он также поддерживает проверку разрешений, возвращаемую клиентскому приложению через сериализатор API. Кроме того, он поддерживает добавление разрешений к действиям по умолчанию и настраиваемым спискам, чтобы ограничить данные, которые они получают для каждого пользователя.
Django Rest Framework Roles
Пакет Django Rest Framework Roles упрощает параметризацию вашего API для разных типов пользователей.
Django REST Framework API Key
Пакет Django REST Framework API Key предоставляет классы разрешений, модели и помощников для добавления авторизации ключа API в ваш API. Его можно использовать для авторизации внутренних или сторонних серверных программ и служб (например, machines), у которых нет учетной записи пользователя. Ключи API надежно хранятся с использованием инфраструктуры хеширования паролей Django, и их можно просмотреть, отредактировать и отозвать в любое время в администраторе Django.
Django Rest Framework Role Filters
Пакет Django Rest Framework Role Filters обеспечивает простую фильтрацию по нескольким типам ролей.
Django Rest Framework PSQ
Пакет Django Rest Framework PSQ - это расширение, обеспечивающее поддержку классов разрешений на основе действий, класс_сериализатора и набора запросов в зависимости от правил на основе разрешений.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
я хотел бы любить Django, но этот бизнес статических и медиа-файлов в средах разработки сводит меня с ума. Пожалуйста, спасите меня от моей глупости.
я на своей машине разработки. У меня есть папка media в корневом каталоге моего проекта.
на settings.py Я: MEDIA_ROOT = '' и MEDIA_URL = '/media/' .
но единственный способ получить медиафайлы-это ссылаться на /media/media/ например, .
я надеюсь (и хочу)
может ли кто-нибудь сказать мне, что здесь происходит, и дать мне простой рецепт для настройки обработки медиафайлов?
@Тимми О'Махони - спасибо! эпический пост, и очень четкий. Но это оставляет пару вопросов:
(1) я должен использовать /media/ и /static/ , а не media/ и static/ as MEDIA_URL и STATIC_URL - я что-то пропустила?
(2) Если collectstatic шланги /static/ , где вы помещаете CSS уровня сайта, например, CSS-файлы сайта? Не в /static/ , очевидно.
(3) я положил их в каталог '_' от корня проекта и набор STATICFILES_DIRS чтобы указать на это - и, похоже, именно там сервер разработки получает свои статические файлы, несмотря на
почему вы сделали MEDIA_ROOT настройки пустым? Это должен быть путь к вашему каталогу мультимедиа. Поскольку, как вы говорите, ваш носитель находится в подкаталоге media , вы должны поместить это в MEDIA_ROOT .
Папку Настройки:
ваш корень проекта должен быть чем-то вроде:
The СМИ папка должна содержать такие вещи, как изображения, загрузки и другие материалы, которые могут быть загружены во время обычного использования веб-сайта (т. е. после завершения разработки)
The static папка должна содержать все CSS / JS и другие материалы, которые являются частью разработки сайт
Settings.py:
MEDIA_ROOT - абсолютный путь сервера к статической папке, указанной выше. Это означает, что это должно быть что-то вроде:
MEDIA_URL относительный URL браузера вы должны получить доступ к медиа-файлам, когда вы смотрите на сайте. Это должно быть (обычно)
аналогично, STATIC_ROOT должно быть что-то вроде
и STATIC_URL be
обслуживание файлов:
теперь, когда вы сказали django, где эти папки должны быть, и правильные URL-адреса для доступа к ним, вам нужно правильно обслуживать все запросы к папкам.
обычно, когда вы находитесь в производстве, вы хотите, чтобы веб-сервер позаботился об обслуживании ваших статических файлов и медиафайлов.
если вы разрабатываете, вы можете просто получить сервер разработки django, чтобы служить им для вас.
чтобы сделать это, вы добавляете некоторые URL-адреса URLS.py как у тебя:
Extra:
если у вас есть несколько приложений, каждый со своими CSS и JS-файлами, вы не захотите бросать их в одну /статическую/ папку. Было бы полезно поместить их во вложенные папки приложений, к которым они принадлежат:
теперь ваш веб-сервер / сервер разработки ищет только статические файлы, где вы сказали ему искать (т. е. корневую статическую папку), поэтому вам нужно собрать все файлы в вложенные папки и скопируйте их в корневую статическую папку. Вы можете сделать это вручную, но django предоставляет команду для этого для вас (это весь смысл статического приложения)
я следовал процедуре Тимми, но я получил ошибку, что нет имени модуля django.views . Когда я использую import django.views в моем virtualenv все работает нормально.e это не проблема с импортом библиотеки.
однако я смог решить эту проблему, выполнив эту процедуру в моем основном файле urls
в своем settings.py Добавьте
в ваших TEMPLATE_CONTEXT_PROCESSORS.В противном случае MEDIA_ROOT не будет работать, когда вы используете его в шаблонах.
Я использую Django 1.10. И моя медиа-папка "uploads" Это конфигурация в my settings.py:
и в шаблоне я поставил имя o моего MEDIA_URL перед de object.имя вместо объекта.url вроде этого:
У меня есть несколько FileFields в мое приложение Джанго, которое может принадлежать разным пользователям. Я ищу хороший способ ограничить доступ к файлам для пользователя, который не является владельцем файла.
каков наилучший способ достичь этого? Есть идеи?
это обертка вокруг конкретного веб-сервера способы отправки файлов веб-клиентам. Это полезно, когда Django необходимо проверить разрешения, связанные с файлами, но не хочет обслуживать фактические байты самого файла. т. е. как обслуживание больших файлов-это не то, для чего создан Django.
чтобы узнать больше о механизме senfile, пожалуйста, прочитайте этот ответ:Django-Понимание X-Sendfile
обновить 2018: обратите внимание, что django-sendfile, похоже, не поддерживается больше; вероятно, он все еще должен работать, однако, если вы хотите более современный пакет с аналогичной функциональностью взгляните наhttps://github.com/edoburu/django-private-storage как комментатор @surfer190 предлагает. Особенно убедитесь, что вы внедрили раздел "оптимизация больших передач файлов"; на самом деле это нужно для всех передач не только для больших файлов.
Если вам нужна только умеренная безопасность, мой подход будет следующим:
1) Когда пользователь загружает файл, создайте для него трудный для угадывания путь. Например, вы можете создать папку со случайным именем для каждого загружаемого файла в /статический папку. Вы можете сделать это довольно просто, используя этот пример кода:
таким образом, будет очень трудно догадаться, где хранятся файлы других пользователей.
2) в базе данных ссылок владельца в папку. Примером схемы может быть:
uploads(id, user_id, file_path)
3) используйте свойство для ваших файловых полей в модели, чтобы ограничить доступ к файлу, таким образом:
как правило, вы не маршрутизируете личные файлы через обычный статический файл, обслуживающий непосредственно через Apache, Nginx или любой веб-сервер, который вы используете. Вместо этого напишите пользовательское представление Django, которое обрабатывает проверку разрешений, а затем возвращает файл в виде потоковой загрузки.
убедитесь, что файлы находятся в специальной папке частной папки и не подвергаются через Django MEDIA_URL или STATIC_URL
напишите представление, которое Уилл!--6-->
убедитесь, что пользователь имеет доступ к файлу в вашей логике просмотра
откройте файл с помощью Python open()
возвращает HTTP-ответ, который получает дескриптор файла в качестве параметра http.HttpResponse(_file, content_type="text/plain")
например, см. download() здесь.
пример из документации:
файл будет доступен, как:
(это будет ограничено по времени и связано с пользователем на этом IP-адресе).
создание маркера для передачи пользователю будет использовать что-то вроде:
Ошибка № 3. Использование старомодных Python-функций вместо представлений-классов (Class-based Views)
Иногда целесообразно использовать в файле приложения views.py маленькие Python-функции, особенно для тестовых или утилитарных представлений. Но обычно в приложениях нужно использовать представления на основе классов (CBV).
CBV — это представления общего назначения, предоставляющие абстрактные классы, реализующие распространённые задачи веб-разработки. CBV созданы профессионалами и покрывают большинство востребованных моделей поведения. У них есть прекрасно структурированный API, и CBV подарят вам возможность наслаждаться всеми преимуществами ООП. Ваш код будет чище и читабельнее. Забудьте о трудностях использования стандартных функций представления (view functions) Django для создания списков, CRUD-операций, обработки форм и т. д. Можно просто расширять подходящий CBV под ваше представление и переопределять (override) функции или свойства класса, конфигурирующие поведение представления (обычно функция возвращает свойство, и вы можете добавить в неё любую логику, которая способна превратить ваш код в спагетти, если вместо CBV вы прибегнете к функциям представления).
Например, можно использовать в проекте разные миксины, которые переопределяют основные модели поведения CBV: создание контекстов представлений, проверка авторизации на уровне строк (on the row level), автосоздание путей шаблонов на основе структур приложения, интегрирование умного кеширования и многое другое.
Я создал пакет Django Template Names, который стандартизирует имена шаблонов для ваших представлений на основе имени приложения и имени класса представления. Я пользуюсь им каждый день и экономлю кучу времени при выборе имён. Просто вставьте миксин в свой CBV — class Detail(TemplateNames, DetailView): — и он начнёт работать! Конечно, можете переопределить мои функции и добавить мобильные адаптивные шаблоны, другие шаблоны для user-agent’ов или что-нибудь ещё.
Ошибка № 7. STATICFILES_DIRS и STATIC_ROOT смущают новичков в Django-разработке
Статичные файлы — это ресурсы (assets), которые не меняются по мере использования приложения. Например, JavaScript, CSS, изображения, шрифты и т. д. В Django они «накапливаются» в публичной директории в ходе развёртывания.
В режиме разработки — python manage.py runserver — Django ищет статичные файлы с помощью настройки STATICFILES_FINDERS. По умолчанию он пытается найти запрошенный файл в папках, перечисленных в STATICFILES_DIRS. Если не находит, то ищет с помощью django.contrib.staticfiles.finders.AppDirectoriesFinder , которая проверяет папку static каждого установленного в проекте приложения. Такая схема позволяет писать многократно используемые приложения, поставляемые со своими собственными статичными файлами.
В production вы раздаёте статичные данные посредством отдельного веб-сервера, например nginx. Он ничего не знает о структуре приложений проекта Django или о том, по каким папкам распределены ваши статичные файлы. К счастью, Django предоставляет нам команду управления сбором статичных данных (collect static management command) — python manage.py collectstatic , которая проходит по STATICFILES_FINDERS и копирует все статичные файлы из папок static приложений, а также из папок, перечисленных в STATICFILES_DIRS , в заданную вами в STATIC_ROOT директорию. Это позволяет разрешать (resolution) ресурсы в виде статичных данных с помощью той же логики, что и у Django-сервера в режиме разработки, и собирать в одном месте для веб-сервера все статичные файлы.
Не забудьте выполнить collectstatic в вашем production-окружении!
Ошибка № 2. Отсутствие привязки зависимостей в файле requirements.txt
Каждый новый проект Python должен начинаться с файла requirements.txt и нового изолированного окружения. Обычно вы с помощью pip/easy_install устанавливаете все пакеты, не забывая о requirements.txt . Обычно проще (возможно, правильнее) развёртывать проекты на серверах или на машинах членов команды.
Также важно в файле requirements.txt выполнять привязку (pin) конкретных версий ваших зависимостей. Обычно разные версии пакета предоставляют разные модули, функции и параметры функций. Даже в младших версиях изменения зависимостей могут оказаться такими, что это сломает ваш пакет. Это очень серьёзная проблема, если у вас живой проект и вы планируете регулярно его развёртывать, так как без системы управления версиями ваша сборочная система всегда будет устанавливать последнюю доступную версию пакета.
В production всегда выполняйте привязку пакетов! Я для этого использую очень хороший инструмент pip-tools. Он предоставляет набор команд, помогающих управлять зависимостями. Инструмент автоматически генерирует requirements.txt , в котором привязаны не просто ваши зависимости, а вообще всё дерево, т. е. и зависимости ваших зависимостей.
Иногда нужно обновить какие-то пакеты в списке зависимостей (например, только фреймворк или утилиту). Если вы прибегаете к pip freeze, то не знаете, какие зависимости используются какими пакетами, и поэтому не можете их обновить. Инструмент pip-tools автоматически привязывает пакеты в соответствии с привязанными вами зависимостями, и поэтому он автоматически решает, какие пакеты нужно обновить. А благодаря используемым комментариям в requirements.txt вы всегда знаете, какой пакет пришёл из какой зависимости.
Если быть ещё более осторожным, то можно делать бекап исходных файлов ваших зависимостей. Храните копию в своей файловой системе, Git-папке, S3-папке, FTP, SFTP — где угодно, лишь бы под рукой. Бывают ситуации, когда исключение из списка относительно небольшого пакета ломает большое количество пакетов в npm. Pip позволяет скачивать все необходимые зависимости в виде исходных файлов. Почитайте об этом подробнее, выполнив команду pip help download .
Ошибка № 6. Приложение всё-в-одном, плохая структура приложения и некорректное размещение ресурсов
Любой Django-проект состоит из нескольких приложений. В терминологии Django приложение — это Python-проект, содержащий как минимум файлы __init__.py и models.py . В последних версиях Django models.py больше не нужен, достаточно только __init__.py .
Django-приложения могут содержать Python-модули, характерные для Django модули (представления, URL’ы, модели, админскую панель, формы, метки шаблонов и т. д.), статичные файлы, шаблоны, миграции базы данных, команды управления, модульные тесты и пр. Нужно разбивать своё монолитное приложение на маленькие многократно используемые приложения с простой логикой.
У вас должна быть возможность полностью описать назначение приложения одним-двумя короткими предложениями. Например: «Позволяет пользователю зарегистрировать и активировать по почте свой аккаунт».
Рекомендуется назвать папку проекта project и положить приложения в project/apps/ . Затем положить все зависимости приложений в собственные подпапки.
- Статичные файлы: project/apps/appname/static/appname/
- Метки шаблона: project/apps/appname/templatetags/appname.py
- Файлы шаблона: project/apps/appname/templates/appname/
Всегда добавляйте имена приложений в виде префиксов в названия подпапок, потому что все статические папки объединяются в одну. И если два или более приложений имеют файл js/core.js , то последнее приложение в settings.INSTALLED_APPLICATIONS переопределит все предыдущие. Однажды я столкнулся с таким багом в своём проекте и потратил около шести часов на отладку, пока не сообразил, что другой разработчик переопределил мой static/admin/js/core.js , потому члены команды реализовали кастомную админскую SPA-панель и дали своим файлам такие же имена.
Вот пример структуры для портального приложения, содержащего много ресурсов и Python-модулей.
Благодаря такой структуре вы можете в любой момент экспортировать приложение в другой Python-пакет и снова его использовать. Можете даже опубликовать его в PyPi в качестве open source пакета или переместить в другую папку. У вас получится примерно такая структура проекта:
Конечно, реальный проект будет сложнее, но такая структура упрощает и делает более прозрачными многие аспекты.
Ошибка № 4. Написание «толстых» (fat) представлений и «тонких» (skinny) моделей
Если у вас логика приложения перенесена из модели в представления, это означает, что в представлениях находится код, принадлежащий модели. То есть представления становятся «толстыми», а модель — «тонкой».
А нужно писать «толстые» модели и «тонкие» представления.
Разбейте логику по маленьким методам в модели. Это позволит использовать их многократно и из многочисленных источников (админский пользовательский интерфейс, пользовательский интерфейс фронтенда, конечные точки API, многочисленные представления). Это займёт всего несколько строк кода, и вам не придётся копипастить кучу строк. Когда в следующий раз будете писать функциональность отправки письма пользователю, расширьте модель с помощью email-функции, а не пишите логику в контроллере.
Это сделает ваш код более удобным для модульного тестирования, потому что вы сможете протестировать логику электронной почты в одном месте, а не делать это в каждом контроллере. Подробнее об этой проблеме почитайте в Django Best Practices. Решение простое: пишите «толстые» модели и «тонкие» представления. Начните это делать уже в следующем проекте или рефакторьте текущий.
Ошибка № 9. Чистый Python для утилит или скриптов
У Django есть отличная фича — команды управления. Используйте их вместо изобретения велосипеда в виде написания скриптов на чистом Python для утилит вашего проекта.
Также обратите внимание на пакет Django Extensions, представляющий собой коллекцию кастомных расширений для Django. Возможно, кто-то уже реализовал ваши команды! Существует много распространённых целевых команд.
Ошибка № 5. Огромный, неповоротливый файл настроек
Даже в новом файле настроек Django-проекта этих настроек содержится множество. А в реальных проектах файл разрастается до 700+ строк, которые трудно сопровождать, особенно когда окружениям разработки, продакшена и стейджинга нужны разные конфигурации.
Вы можете вручную разделить конфигурационный файл и создать отдельные загрузчики, но я хочу порекомендовать отличный, хорошо протестированный Python-пакет Django Split Settings, соавтором которого я являюсь.
Пакет предоставляет две функции — optional и include , которые поддерживают подстановки (wildcards) для путей и импортируют ваши конфигурационные файлы в тот же контекст. Благодаря этому можно просто создавать конфигурации с помощью объявления конфигурационных записей в ранее загруженных файлах. Пакет никак не влияет на производительность Django и может применяться в любых проектах.
Вот пример минимальной конфигурации:
Читайте также: