10 июл. 2008 г.

Django из коробки

14 проект на Django стал последней каплей :). Нет, серьезно слоган джанго: "не повторяйте себя!", так? Каждый раз создавая проект я скурпулезно переношу в него все свои старые наработки и только потом приступаю к написанию.

"Это плохо"- подумал я, и сделал seleton проект.

Посмотреть его можно тут: svn://std.tsogu.ru/skeleton.

Структура файлов пока что такая:

skeleton

  • skeletonapp
    • templates
      • 404.html
      • 500.html
      • base.html
      • index.html
    • __init__.py
    • models.py
    • urls.py
    • views.py
  • userapp
    • templates
      • index.html
    • __init__.py
    • models.py
    • urls.py
    • views.py
  • __init__.py
  • context_processors.py
  • manage.py
  • settings.py
  • snippets.py
  • urls.py

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

settings.py:

import os
working_dir = os.path.dirname(__file__)

 

MEDIA_ROOT = working_dir + '/media/'

TEMPLATE_DIRS = (
    working_dir + '/skeletonapp/templates/',
    working_dir + '/userapp/templates/',
)

...

ADMIN_MEDIA_ROOT = '/usr/local/lib/python/site-packages/django/contrib/admin/media/'

 

...

COMMON_MEDIA_URL = 'http://std.tsogu.ru/media/'

 

...

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "skeleton.context_processors.common_media_url",
    "skeleton.context_processors.admin_media_prefix",
    "skeleton.context_processors.trac",
)

...

## Информация о проекте в trac.std.tsogu.ru
TRAC_URL = 'http://trac.std.tsogu.ru/'
TRAC_COMPONENT_NAME = 'skeleton'
TRAC_VERSION = 'skeleton_ver1'
TRAC_MILESTONE = 'skeleton_ver2'
TRAC_OWNER = 'markeev'

...

AUTH_PROFILE_MODULE = "userapp.UserProfile"

Комментарии, по большей части, излишни. Добавлю только, что большая часть непонятных переменных используется в context processors (или как это будет по русски? :) ).

urls.py (в корне проекта):

(r'^media/(?P<path>.*)', 'django.views.static.serve', {'document_root':settings.MEDIA_ROOT,'show_indexes': True}),
(r'^adminmedia/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.ADMIN_MEDIA_ROOT, 'show_indexes': True}),

Известный косяк с потерей путей к админским css файлам лечится вышеобозначенными напильниками.

context_processors.py:

def common_media_url(request):
    from django.conf import settings
    return {
        'COMMON_MEDIA_URL': settings.COMMON_MEDIA_URL,
        }

def admin_media_prefix(request):
    from django.conf import settings
    return {
        'ADMIN_MEDIA_PREFIX': settings.ADMIN_MEDIA_PREFIX,
        }

def trac(request):
    from django.conf import settings
    try: username = request.username
    except: username = 'anonymous'
    return {
        'username': username,
        'TRAC_URL': settings.TRAC_URL,
        'TRAC_COMPONENT_NAME': settings.TRAC_COMPONENT_NAME,
        'TRAC_VERSION': settings.TRAC_VERSION,
        'TRAC_MILESTONE': settings.TRAC_MILESTONE,
        'TRAC_OWNER': settings.TRAC_OWNER,
        }

С первыми двумя функциями все ясно: передают в шаблон значения COMMON_MEDIA_URL и ADMIN_MEDIA_PREFIX.

Функция trac нужна для заполнения страниц с ошибками:

404.html:

{% extends "base.html" %}

{% block title %}404 - Запрошенная страница не найдена{% endblock %}

{% block content %}
<h1>404 - Запрошенная страница не найдена</h1>
<p>Страница не найдена. <a href="{{ TRAC_URL }}newticket?reporter={{username}}&component={{ TRAC_COMPONENT_NAME }}&milestone={{TRAC_MILESTONE}}&version={{TRAC_VERSION}}&owner={{TRAC_OWNER}}">Сообщить об ошибке!</a></p>
<p>Дополнительная информация на <a href="{{ TRAC_URL }}wiki/{{ TRAC_COMPONENT_NAME }}">странице проекта.</p>
{% endblock %}

snippets.py использую для хранения и использования понравившихся сниппетов. Например очень удобный 821:

from django.shortcuts import render_to_response

from django.template import RequestContext

def render_to(template_path):
    def decorator(func):
        def wrapper(request, *args, **kw):
            output = func(request, *args, **kw)
            if not isinstance(output, dict):
                return output
            return render_to_response(template_path, output,
                context_instance=RequestContext(request))
        return wrapper
    return decorator

 

Осталось только одно, про что я не рассказал - COMMON_MEDIA_URL. Параметр используется в шаблонах для подключения общих для всей информационной службы css и javascript фреймворков.

Комментариев нет: