Работа с файлами в Django

Эта статья описывает принципы работы с файлами в Django проекте. Django разделяет файлы на два типа:

  1. Файлы прописанные в коде или шаблонах. Назовем их STATIC файлы, они известны и имеются до начала работы приложения.
  2. Файлы, появляются в результате работы приложения. Например, загружаются пользователями. Назовем их MEDIA файлы.

Чтобы Django начала отдавать загруженные пользователем MEDIA файлы, достаточно прописать в urls.py:

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

и добавить к urlpatterns

 + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Теперь urlpatterns может выглядеть так:

urlpatterns = patterns('',
 url(r'^weblog/', include('zinnia.urls')),
 url(r'^comments/', include('django.contrib.comments.urls')),
 url(r'^admin/', include(admin.site.urls)),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

https://docs.djangoproject.com/en/1.5/howto/static-files/

Рассмотрим работу с файлами подробнее.

Настройка Django для работы с файлами

Рассмотрим один из вариантов настройки:

import os

_PATH = os.path.abspath(os.path.dirname(__file__))

MEDIA_ROOT = os.path.join(_PATH, 'files', 'media')
MEDIA_URL = '/media/'

STATIC_ROOT = os.path.join(_PATH, 'files', 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(_PATH, 'static'),
)
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

ADMIN_MEDIA_PREFIX = '/static/admin/'

Что такое _PATH должно быть понятно. В проекте находится папка files, которая содержит папку media для MEDIA файлов и папка static для STATIC файлов. Очень важно разделить их таким образом. Потом можете получить много проблем не разделив их изначально. Это позволит вам легко использовать различные версии файлов, расположив их по разным папкам.

Но почему files в папке проекта? Потому что это удобно при разработке. На реальном сервере рекомендуется вынести files из проекта и изменить MEDIA_ROOT и STATIC_ROOT.

STATIC файлы располагаются в <_PATH>/static. Это используемые js и css файлы. Приложение django.contrib.staticfiles соберет все STATIC файлы из STATICFILES_DIRSи из соответствующих папок приложений и перенесет в STATIC_ROOT.

Подведем итоги:

  • В STATIC добавляются файлы из проекта(смотрите STATICFILES_DIRS иFileSystemFinder), а так же AppDirectoriesFinder добавит файлы из папкиstatic в приложениях.
  • MEDIA и STATIC файла лучше разделить(смотрите STATIC_ROOT и MEDIA_ROOT).
  • STATIC_ROOT и MEDIA_ROOT лучше вынести из проекта на «продакшине».

И не забудьте добавить «слеш» в конце STATIC_URL и MEDIA_URL!

Как настроить выдачу файлов для dev-сервера

Как упоминалось выше, лучше отдавать файлы через специальный сервер, например Nginx или Apache. Но при разработке это лишние проблемы. Можно легко настроить выдачу файлов средствами Django. Предполагается что при разработке DEBUG всегда True, а на сервере — False. Добавим в urls.py:

from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()

Все просто. Учтите что urlpatterns изменится только при DEBUG == True и если MEDIA_URL и STATIC_URL не абсолютны(то есть без http://).

Как использовать STATIC файлы в шаблонах

{% load staticfiles %}

<img src="{% static 'myapp/img/logo.png' %}" />

Как использовать MEDIA файлы в шаблоне

Это на много проще. Объект FieldFile, возвращаемый ImageField и FileField, содержит path и url:

<img src="{{ some_model.some_image_field.url }}" />

Как добавить STATIC файлы

Так как имена STATIC файлов используются в коде, шаблонах, лучше всего хранить их в VCS вместе с кодом. STATIC файлы собираются(находят и копируются или через simlink) с помощью «finder»-ов. Вам не обязательно знать как все это происходит, главное хранить файлы в нужном месте.

При разработке независимого приложения для Django файлы нужно хранить в папкеstatic в вашем приложении:

$ ls -1
models.py
static/
templates/
views.py

Файлы, которые относятся конкретно к проекту нужно хранить в папка указанных вSTATICFILES_DIRS:

>>> from django.conf import settings
>>> settings.STATICFILES_DIRS
('/opt/myproject/src/project/static',)

Как загрузить MEDIA файлы

MEDIA файлы в основном используются в моделях с полями FileField и ImageField. Например:

# models.py
from django.db import models
from django.forms.models import modelform_factory

class MediaModel(models.Model):
    media_file = models.FileField(upload_to='user_media')

MediaForm = modelform_factory(MediaModel)

# views.py
def media_create(request):
    if request.method == "POST":
        form = MediaForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('media-list'))
    else:
        form = MediaForm()
    return render_to_response('usermedia/create/html', {'form': form})

we’ll now add a stylesheet and an image.

Aside from the HTML generated by the server, web applications generally need to serve additional files — such as images, JavaScript, or CSS — necessary to render the complete web page. In Django, we refer to these files as “static files”.

For small projects, this isn’t a big deal, because you can just keep the static files somewhere your web server can find it. However, in bigger projects – especially those comprised of multiple apps – dealing with the multiple sets of static files provided by each application starts to get tricky.

That’s what django.contrib.staticfiles is for: it collects static files from each of your applications (and any other places you specify) into a single location that can easily be served in production.

Customize your app’s look and feel

First, create a directory called static in your polls directory. Django will look for static files there, similarly to how Django finds templates inside polls/templates/.

Django’s STATICFILES_FINDERS setting contains a list of finders that know how to discover static files from various sources. One of the defaults is AppDirectoriesFinder which looks for a “static” subdirectory in each of the INSTALLED_APPS, like the one in polls we just created. The admin site uses the same directory structure for its static files.

Within the static directory you have just created, create another directory called polls and within that create a file called style.css. In other words, your stylesheet should be atpolls/static/polls/style.css. Because of how the AppDirectoriesFinder staticfile finder works, you can refer to this static file in Django simply as polls/style.css, similar to how you reference the path for templates.

Static file namespacing

Just like templates, we might be able to get away with putting our static files directly inpolls/static (rather than creating another polls subdirectory), but it would actually be a bad idea. Django will choose the first static file it finds whose name matches, and if you had a static file with the same name in a different application, Django would be unable to distinguish between them. We need to be able to point Django at the right one, and the easiest way to ensure this is by namespacing them. That is, by putting those static files inside another directory named for the application itself.

Put the following code in that stylesheet (polls/static/polls/style.css):

li a {
    color: green;
}

Next, add the following at the top of polls/templates/polls/index.html:

{% load staticfiles %}

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />

{% load staticfiles %} loads the {% static %} template tag from the staticfiles template library. The {% static %} template tag generates the absolute URL of the static file.

That’s all you need to do for development. Reload http://localhost:8000/polls/ and you should see that the poll links are green (Django style!) which means that your stylesheet was properly loaded.

Adding a background-image

Next, we’ll create a subdirectory for images. Create an images subdirectory in the polls/static/polls/directory. Inside this directory, put an image called background.gif. In other words, put your image inpolls/static/polls/images/background.gif.

Then, add to your stylesheet (polls/static/polls/style.css):

body {
    background: white url("images/background.gif") no-repeat right bottom;
}

Reload http://localhost:8000/polls/ and you should see the background loaded in the bottom right of the screen.

Warning

Of course the {% static %} template tag is not available for use in static files like your stylesheet which aren’t generated by Django. You should always use relative paths to link your static files between each other, because then you can change STATIC_URL (used by thestatic template tag to generate its URLs) without having to modify a bunch of paths in your static files as well.

These are the basics. For more details on settings and other bits included with the framework see the static files howto and the staticfiles referenceDeploying static files discusses how to use static files on a real server.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *