Изучая django, я неожиданно столкнулся с проблемой. Я постоянно меняю структуру сайта (url.py) и мне приходиться постоянно вводить в адресной строке браузера новые url. И тут я подумал, что неплохо было добавить к моему тестовому сайту менюшку, которая будет брать список URL из url.py. Первым делом я начал смотреть готовые решения, которых, кстати, не оказалось. Также был вариант использовать БД и sitemap для редактирования ссылок. А что делать, если я не хочу использовать БД? Загуглив еще разок я нашел замечательную функцию get_resolver из django.core.urlresolvers и решил написать собственный генератор списка url.
Задача стояла следющая: автоматически генерировать список URL, которые находятся в url.py
и добавлять эти URL в собственный шаблон в виде меню.
В результате получилась следующая функция
Тут необходимо немножко пояснить:
Для того чтобы все ссылки были абсолютными, а не относительными используется функция gethostbyname.
иначе при переходе на ссылку "http://localhost/main_page/" сгенериется динамически меню с ссылкой:
http://localhost/main_page/main_page/
Поэтому я решил использовать абсолютный путь для генерирования меню.
также если в /etc/hosts вы указали, что localhost это mysite.com, то можно писать
По умолчанию get_links() берет url из urlpatterns, а имя ссылки соответствует названию функции,
что не всегда этично. Для того чтобы указать назавания ссылок можно использовать простой if.
Тогда вместо
следует писать
Теперь в каждой функции представления мы можем писать
В шаблоне реализуем меню (при необходимости можно добавить чуть-чуть javascript):
Но, определять в каждом представлении переменную links, это не очень кошерно.
Получается что links = get_links() будет присутствовать в каждом предствлении.
И если мы его забудем добавить, то не сгенерируется меню в шаблоне.
Отсюда еще одна задача.
Добавить links = get_links() в locals().
Для этого пишем еще одну функцию:
После этого мы можем использовать ее при генерации шаблона:
Ремарка: статья называется "простое меню...", потому что в функции get_links() отсутвует парсинг регулярных выражений.
Но этого вполне достаточно для того, чтобы понять, как извлекать значения urlpatterns из ulr.py.
Исходники проеакта на django.
Задача стояла следющая: автоматически генерировать список URL, которые находятся в url.py
и добавлять эти URL в собственный шаблон в виде меню.
В результате получилась следующая функция
import socket def get_links(): links = [] address = socket.gethostbyname_ex(socket.gethostname())[-1][0] # for IP #address = socket.gethostbyname_ex(socket.gethostname())[0] # for name resolver = get_resolver(None).reverse_dict.items() for i in sorted(resolver, key=lambda resolve: resolve[1]): short_url = i[1][0][0][0] url_desc = {"url":str(address) + "/" + short_url} url_desc["name"] = str(i[0]).split(' ')[1] links.append(url_desc) return links
Тут необходимо немножко пояснить:
Для того чтобы все ссылки были абсолютными, а не относительными используется функция gethostbyname.
иначе при переходе на ссылку "http://localhost/main_page/" сгенериется динамически меню с ссылкой:
http://localhost/main_page/main_page/
Поэтому я решил использовать абсолютный путь для генерирования меню.
также если в /etc/hosts вы указали, что localhost это mysite.com, то можно писать
address = "mysite.com"
По умолчанию get_links() берет url из urlpatterns, а имя ссылки соответствует названию функции,
что не всегда этично. Для того чтобы указать назавания ссылок можно использовать простой if.
def set_name(url, default_value): if url == r'': return 'root' elif url == r'custom_hello/': return 'Custom menu name 2' else: return default_value
Тогда вместо
url_desc["name"] = str(i[0]).split(' ')[1]
следует писать
url_desc["name"] = set_name(short_url, str(i[0]).split(' ')[1])
Теперь в каждой функции представления мы можем писать
links = get_links() return render_to_response('template.html',locals())
В шаблоне реализуем меню (при необходимости можно добавить чуть-чуть javascript):
{% for link in links %} <a href="http://{{ link.url }}">{{ link.name }}</a> {% if not forloop.last %}|{% endif %} {% endfor %}
Но, определять в каждом представлении переменную links, это не очень кошерно.
Получается что links = get_links() будет присутствовать в каждом предствлении.
И если мы его забудем добавить, то не сгенерируется меню в шаблоне.
Отсюда еще одна задача.
Добавить links = get_links() в locals().
Для этого пишем еще одну функцию:
def get_locals_with_links(local_dict): new_d = {} for i in dict(local_dict).copy().items(): if str(i[0]).find("__") == -1: new_d[str(i[0])] = i[1] new_d.update({'links':get_links()}) return new_d
После этого мы можем использовать ее при генерации шаблона:
from URL_helper import get_locals_with_links def hello(request): hello = "Hello, World!!!" return render_to_response('template.html',get_locals_with_links(locals()))
Ремарка: статья называется "простое меню...", потому что в функции get_links() отсутвует парсинг регулярных выражений.
Но этого вполне достаточно для того, чтобы понять, как извлекать значения urlpatterns из ulr.py.
Исходники проеакта на django.
Комментариев нет:
Отправить комментарий