Skip to content
Snippets Groups Projects
urls.py 4.49 KiB
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.conf.urls import include, url

from .models import newsbox_models
from .views import NewsboxArchiveView, NewsboxYearArchiveView, \
    NewsboxMonthArchiveView, NewsboxDayArchiveView, NewsboxDetailView


def _get_view(view, model, **kwargs):
    if hasattr(view, 'as_view'):
        view_kwargs = {'model': model}
        view_kwargs.update(kwargs)
        return view.as_view(**view_kwargs)
    elif callable(view):
        return view
    else:
        raise Exception('Wrong view type ! must be a Class Based view or a collable')


def get_urls(
    archive_view=NewsboxArchiveView,
    year_archive_view=NewsboxYearArchiveView,
    month_archive_view=NewsboxMonthArchiveView,
    day_archive_view=NewsboxDayArchiveView,
    detail_view=NewsboxDetailView,
    models=newsbox_models,
    url_prefix='%(app_label)s/%(model_name)s/',
    url_name_prefix='%(model_name)s_',
    url_namespace='%(app_label)s',
):
    """
    auto create urls for newsbox models. You can personalize used views with *_view parameters:
    earch paramater can be a view func, a class View, or a 2-tuple with a class View and a dict for
    extra args to the view (eg: an other pagination than the default one, a specific template etc.)
    If a *_view parameter is None, its URL is not set.

    urls are by default `^<prefix><url>$`:
        - <url> depends on the view (eg: `(?P<year>\d{4})/`) for the year archive view)
        - <prefix> is by default `<app_label>/<model_name>/` and you can overwrite it via
          `url_prefix`.
    urls names are by default `<prefix><type>`:
        - <type> is 'list' or 'detail'
        - <prefix> is by default '<model_name>_'. You can overwrite it via `url_name_prefix`
    urls are namespaced with <appl_label> but you can overwrite it via `url_namespace`

    By default, this func will create urls for all models build with newsbox. You can limit to
    specific models via the "models" parameter. It must be an iterable.
    """
    if type(archive_view) is dict:
        archive_view, archive_view_kwargs = NewsboxArchiveView, archive_view
    else:
        archive_view_kwargs = {}
    if type(year_archive_view) is dict:
        year_archive_view, year_archive_view_kwargs = NewsboxYearArchiveView, year_archive_view
    else:
        year_archive_view_kwargs = {}
    if type(month_archive_view) is dict:
        month_archive_view, month_archive_view_kwargs = NewsboxMonthArchiveView, month_archive_view
    else:
        month_archive_view_kwargs = {}
    if type(day_archive_view) is dict:
        day_archive_view, day_archive_view_kwargs = NewsboxDayArchiveView, day_archive_view
    else:
        day_archive_view_kwargs = {}
    if type(detail_view) is dict:
        detail_view, detail_view_kwargs = NewsboxDetailView, detail_view
    else:
        detail_view_kwargs = {}

    root_url = r'^$'
    year_url = r'^(?P<year>\d{4})/$'
    month_url = r'^%s(?P<month>\d{2})/$' % year_url[1:-1]
    day_url = r'^%s(?P<day>\d{2})/$' % month_url[1:-1]
    slug_url = r'^%s(?P<slug>[-\w]+)/$' % day_url[1:-1]

    urls = []
    for model in models:
        model_urls = []
        model_infos = {'app_label': model._meta.app_label.lower(),
                       'model_name': model.__name__.lower()}
        namespace = url_namespace % model_infos if url_namespace else ''
        name_prefix = url_name_prefix % model_infos if url_name_prefix else ''
        prefix = url_prefix % model_infos if url_prefix else ''

        if archive_view:
            view = _get_view(archive_view, model, **archive_view_kwargs)
            model_urls.append(url(root_url, view, name='%slist' % name_prefix))

        if year_archive_view:
            view = _get_view(year_archive_view, model, **year_archive_view_kwargs)
            model_urls.append(url(year_url, view, name='%slist' % name_prefix))

        if month_archive_view:
            view = _get_view(month_archive_view, model, **month_archive_view_kwargs)
            model_urls.append(url(month_url, view, name='%slist' % name_prefix))

        if day_archive_view:
            view = _get_view(day_archive_view, model, **day_archive_view_kwargs)
            model_urls.append(url(day_url, view, name='%slist' % name_prefix))

        if detail_view:
            view = _get_view(detail_view, model, **detail_view_kwargs)
            model_urls.append(url(slug_url, view, name='%sdetail' % name_prefix))
        if model_urls:
            urls.append(url(r'^%s' % prefix, include(model_urls, namespace=namespace)))
    return urls