Top

telemeta.views.geo module

# -*- coding: utf-8 -*-
# Copyright (C) 2007-2010 Samalyse SARL
# Copyright (C) 2010-2012 Parisson SARL

# This file is part of Telemeta.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Authors: Olivier Guilyardi <olivier@samalyse.com>
#          Guillaume Pellerin <yomguy@parisson.com>


from telemeta.views.core import *


class GeoView(object):
    """Provide Geo web UI methods"""

    def list_continents(self, request):
        continents = MediaItem.objects.all().countries(group_by_continent=True)
        return render(request, 'telemeta/geo_continents.html',
                    {'continents': continents, 'gmap_key': settings.TELEMETA_GMAP_KEY })

    def country_info(self, request, id):
        country = Location.objects.get(pk=id)
        return render(request, 'telemeta/country_info.html', {
            'country': country, 'continent': country.continents()[0]})

    def list_countries(self, request, continent):
        continent = Location.objects.by_flatname(continent)[0]
        countries = MediaItem.objects.by_location(continent).countries()

        return render(request, 'telemeta/geo_countries.html', {
            'continent': continent,
            'countries': countries
        })

    def list_country_collections(self, request, continent, country):
        continent = Location.objects.by_flatname(continent)[0]
        country = Location.objects.by_flatname(country)[0]
        objects = MediaCollection.objects.enriched().by_location(country)
        return list_detail.object_list(request, objects,
            template_name='telemeta/geo_country_collections.html', paginate_by=20,
            extra_context={'country': country, 'continent': continent})

    def list_country_items(self, request, continent, country):
        continent = Location.objects.by_flatname(continent)[0]
        country = Location.objects.by_flatname(country)[0]
        objects = MediaItem.objects.enriched().by_location(country)
        return list_detail.object_list(request, objects,
            template_name='telemeta/geo_country_items.html', paginate_by=20,
            extra_context={'country': country, 'continent': continent})


class GeoCountryCollectionView(ListView):

    model = MediaCollection
    template_name = 'telemeta/geo_country_collections.html'
    paginate_by = 20

    def get_queryset(self):
        country = self.kwargs['country']
        continent = self.kwargs['continent']
        self.continent = Location.objects.by_flatname(continent)[0]
        self.country = Location.objects.by_flatname(country)[0]
        return MediaCollection.objects.enriched().by_location(self.country)

    def get_context_data(self, *args, **kwargs):
        context = super(GeoCountryCollectionView, self).get_context_data(*args, **kwargs)
        context['country'] = self.country
        context['continent'] =  self.continent
        context['count'] = self.object_list.count()
        return context


class GeoCountryItemView(ListView):

    model = MediaItem
    template_name = 'telemeta/geo_country_items.html'
    paginate_by = 20

    def get_queryset(self):
        country = self.kwargs['country']
        continent = self.kwargs['continent']
        self.continent = Location.objects.by_flatname(continent)[0]
        self.country = Location.objects.by_flatname(country)[0]
        return MediaItem.objects.enriched().by_location(self.country)

    def get_context_data(self, *args, **kwargs):
        context = super(GeoCountryItemView, self).get_context_data(*args, **kwargs)
        context['country'] = self.country
        context['continent'] =  self.continent
        context['count'] = self.object_list.count()
        return context

Module variables

var ITEM_PUBLIC_ACCESS_CHOICES

var ITEM_TRANSODING_STATUS

var PUBLIC_ACCESS_CHOICES

var SCOPE_CHOICES

var TYPE_CHOICES

var app_name

var code_linesep

var collection_code_regex

var collection_published_code_regex

var collection_unpublished_code_regex

var default_decoding

var default_encoding

var engine

var eol

var ext

var item_code_regex

var item_published_code_regex

var item_unpublished_code_regex

var mime_type

var mods

var private_extra_types

var public_extra_types

var resource_code_regex

var strict_code

Classes

class GeoCountryCollectionView

class GeoCountryCollectionView(ListView):

    model = MediaCollection
    template_name = 'telemeta/geo_country_collections.html'
    paginate_by = 20

    def get_queryset(self):
        country = self.kwargs['country']
        continent = self.kwargs['continent']
        self.continent = Location.objects.by_flatname(continent)[0]
        self.country = Location.objects.by_flatname(country)[0]
        return MediaCollection.objects.enriched().by_location(self.country)

    def get_context_data(self, *args, **kwargs):
        context = super(GeoCountryCollectionView, self).get_context_data(*args, **kwargs)
        context['country'] = self.country
        context['continent'] =  self.continent
        context['count'] = self.object_list.count()
        return context

Ancestors (in MRO)

  • GeoCountryCollectionView
  • django.views.generic.list.ListView
  • django.views.generic.list.MultipleObjectTemplateResponseMixin
  • django.views.generic.base.TemplateResponseMixin
  • django.views.generic.list.BaseListView
  • django.views.generic.list.MultipleObjectMixin
  • django.views.generic.base.ContextMixin
  • django.views.generic.base.View
  • __builtin__.object

Class variables

var allow_empty

var content_type

var context_object_name

var http_method_names

var model

var page_kwarg

var paginate_by

var paginate_orphans

var paginator_class

var queryset

var response_class

var template_name

var template_name_suffix

Methods

def __init__(

self, **kwargs)

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

def __init__(self, **kwargs):
    """
    Constructor. Called in the URLconf; can contain helpful extra
    keyword arguments, and other things.
    """
    # Go through keyword arguments, and either save their values to our
    # instance, or raise an error.
    for key, value in six.iteritems(kwargs):
        setattr(self, key, value)

def as_view(

cls, **initkwargs)

Main entry point for a request-response process.

@classonlymethod
def as_view(cls, **initkwargs):
    """
    Main entry point for a request-response process.
    """
    # sanitize keyword arguments
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError("You tried to pass in the %s method name as a "
                            "keyword argument to %s(). Don't do that."
                            % (key, cls.__name__))
        if not hasattr(cls, key):
            raise TypeError("%s() received an invalid keyword %r. as_view "
                            "only accepts arguments that are already "
                            "attributes of the class." % (cls.__name__, key))
    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)
    # take name and docstring from class
    update_wrapper(view, cls, updated=())
    # and possible attributes set by decorators
    # like csrf_exempt from dispatch
    update_wrapper(view, cls.dispatch, assigned=())
    return view

def dispatch(

self, request, *args, **kwargs)

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

def get(

self, request, *args, **kwargs)

def get(self, request, *args, **kwargs):
    self.object_list = self.get_queryset()
    allow_empty = self.get_allow_empty()
    if not allow_empty:
        # When pagination is enabled and object_list is a queryset,
        # it's better to do a cheap query than to load the unpaginated
        # queryset in memory.
        if (self.get_paginate_by(self.object_list) is not None
            and hasattr(self.object_list, 'exists')):
            is_empty = not self.object_list.exists()
        else:
            is_empty = len(self.object_list) == 0
        if is_empty:
            raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.")
                    % {'class_name': self.__class__.__name__})
    context = self.get_context_data()
    return self.render_to_response(context)

def get_allow_empty(

self)

Returns True if the view should display empty lists, and False if a 404 should be raised instead.

def get_allow_empty(self):
    """
    Returns ``True`` if the view should display empty lists, and ``False``
    if a 404 should be raised instead.
    """
    return self.allow_empty

def get_context_data(

self, *args, **kwargs)

def get_context_data(self, *args, **kwargs):
    context = super(GeoCountryCollectionView, self).get_context_data(*args, **kwargs)
    context['country'] = self.country
    context['continent'] =  self.continent
    context['count'] = self.object_list.count()
    return context

def get_context_object_name(

self, object_list)

Get the name of the item to be used in the context.

def get_context_object_name(self, object_list):
    """
    Get the name of the item to be used in the context.
    """
    if self.context_object_name:
        return self.context_object_name
    elif hasattr(object_list, 'model'):
        return '%s_list' % object_list.model._meta.model_name
    else:
        return None

def get_paginate_by(

self, queryset)

Get the number of items to paginate by, or None for no pagination.

def get_paginate_by(self, queryset):
    """
    Get the number of items to paginate by, or ``None`` for no pagination.
    """
    return self.paginate_by

def get_paginate_orphans(

self)

Returns the maximum number of orphans extend the last page by when paginating.

def get_paginate_orphans(self):
    """
    Returns the maximum number of orphans extend the last page by when
    paginating.
    """
    return self.paginate_orphans

def get_paginator(

self, queryset, per_page, orphans=0, allow_empty_first_page=True, **kwargs)

Return an instance of the paginator for this view.

def get_paginator(self, queryset, per_page, orphans=0,
                  allow_empty_first_page=True, **kwargs):
    """
    Return an instance of the paginator for this view.
    """
    return self.paginator_class(
        queryset, per_page, orphans=orphans,
        allow_empty_first_page=allow_empty_first_page, **kwargs)

def get_queryset(

self)

def get_queryset(self):
    country = self.kwargs['country']
    continent = self.kwargs['continent']
    self.continent = Location.objects.by_flatname(continent)[0]
    self.country = Location.objects.by_flatname(country)[0]
    return MediaCollection.objects.enriched().by_location(self.country)

def get_template_names(

self)

Return a list of template names to be used for the request. Must return a list. May not be called if render_to_response is overridden.

def get_template_names(self):
    """
    Return a list of template names to be used for the request. Must return
    a list. May not be called if render_to_response is overridden.
    """
    try:
        names = super(MultipleObjectTemplateResponseMixin, self).get_template_names()
    except ImproperlyConfigured:
        # If template_name isn't specified, it's not a problem --
        # we just start with an empty list.
        names = []
    # If the list is a queryset, we'll invent a template name based on the
    # app and model name. This name gets put at the end of the template
    # name list so that user-supplied names override the automatically-
    # generated ones.
    if hasattr(self.object_list, 'model'):
        opts = self.object_list.model._meta
        names.append("%s/%s%s.html" % (opts.app_label, opts.model_name, self.template_name_suffix))
    return names

def http_method_not_allowed(

self, request, *args, **kwargs)

def http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning('Method Not Allowed (%s): %s', request.method, request.path,
        extra={
            'status_code': 405,
            'request': self.request
        }
    )
    return http.HttpResponseNotAllowed(self._allowed_methods())

def options(

self, request, *args, **kwargs)

Handles responding to requests for the OPTIONS HTTP verb.

def options(self, request, *args, **kwargs):
    """
    Handles responding to requests for the OPTIONS HTTP verb.
    """
    response = http.HttpResponse()
    response['Allow'] = ', '.join(self._allowed_methods())
    response['Content-Length'] = '0'
    return response

def paginate_queryset(

self, queryset, page_size)

Paginate the queryset, if needed.

def paginate_queryset(self, queryset, page_size):
    """
    Paginate the queryset, if needed.
    """
    paginator = self.get_paginator(
        queryset, page_size, orphans=self.get_paginate_orphans(),
        allow_empty_first_page=self.get_allow_empty())
    page_kwarg = self.page_kwarg
    page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
    try:
        page_number = int(page)
    except ValueError:
        if page == 'last':
            page_number = paginator.num_pages
        else:
            raise Http404(_("Page is not 'last', nor can it be converted to an int."))
    try:
        page = paginator.page(page_number)
        return (paginator, page, page.object_list, page.has_other_pages())
    except InvalidPage as e:
        raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
                            'page_number': page_number,
                            'message': str(e)
        })

def render_to_response(

self, context, **response_kwargs)

Returns a response, using the response_class for this view, with a template rendered with the given context.

If any keyword arguments are provided, they will be passed to the constructor of the response class.

def render_to_response(self, context, **response_kwargs):
    """
    Returns a response, using the `response_class` for this
    view, with a template rendered with the given context.
    If any keyword arguments are provided, they will be
    passed to the constructor of the response class.
    """
    response_kwargs.setdefault('content_type', self.content_type)
    return self.response_class(
        request = self.request,
        template = self.get_template_names(),
        context = context,
        **response_kwargs
    )

class GeoCountryItemView

class GeoCountryItemView(ListView):

    model = MediaItem
    template_name = 'telemeta/geo_country_items.html'
    paginate_by = 20

    def get_queryset(self):
        country = self.kwargs['country']
        continent = self.kwargs['continent']
        self.continent = Location.objects.by_flatname(continent)[0]
        self.country = Location.objects.by_flatname(country)[0]
        return MediaItem.objects.enriched().by_location(self.country)

    def get_context_data(self, *args, **kwargs):
        context = super(GeoCountryItemView, self).get_context_data(*args, **kwargs)
        context['country'] = self.country
        context['continent'] =  self.continent
        context['count'] = self.object_list.count()
        return context

Ancestors (in MRO)

  • GeoCountryItemView
  • django.views.generic.list.ListView
  • django.views.generic.list.MultipleObjectTemplateResponseMixin
  • django.views.generic.base.TemplateResponseMixin
  • django.views.generic.list.BaseListView
  • django.views.generic.list.MultipleObjectMixin
  • django.views.generic.base.ContextMixin
  • django.views.generic.base.View
  • __builtin__.object

Class variables

var allow_empty

var content_type

var context_object_name

var http_method_names

var model

var page_kwarg

var paginate_by

var paginate_orphans

var paginator_class

var queryset

var response_class

var template_name

var template_name_suffix

Methods

def __init__(

self, **kwargs)

Constructor. Called in the URLconf; can contain helpful extra keyword arguments, and other things.

def __init__(self, **kwargs):
    """
    Constructor. Called in the URLconf; can contain helpful extra
    keyword arguments, and other things.
    """
    # Go through keyword arguments, and either save their values to our
    # instance, or raise an error.
    for key, value in six.iteritems(kwargs):
        setattr(self, key, value)

def as_view(

cls, **initkwargs)

Main entry point for a request-response process.

@classonlymethod
def as_view(cls, **initkwargs):
    """
    Main entry point for a request-response process.
    """
    # sanitize keyword arguments
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError("You tried to pass in the %s method name as a "
                            "keyword argument to %s(). Don't do that."
                            % (key, cls.__name__))
        if not hasattr(cls, key):
            raise TypeError("%s() received an invalid keyword %r. as_view "
                            "only accepts arguments that are already "
                            "attributes of the class." % (cls.__name__, key))
    def view(request, *args, **kwargs):
        self = cls(**initkwargs)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)
    # take name and docstring from class
    update_wrapper(view, cls, updated=())
    # and possible attributes set by decorators
    # like csrf_exempt from dispatch
    update_wrapper(view, cls.dispatch, assigned=())
    return view

def dispatch(

self, request, *args, **kwargs)

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

def get(

self, request, *args, **kwargs)

def get(self, request, *args, **kwargs):
    self.object_list = self.get_queryset()
    allow_empty = self.get_allow_empty()
    if not allow_empty:
        # When pagination is enabled and object_list is a queryset,
        # it's better to do a cheap query than to load the unpaginated
        # queryset in memory.
        if (self.get_paginate_by(self.object_list) is not None
            and hasattr(self.object_list, 'exists')):
            is_empty = not self.object_list.exists()
        else:
            is_empty = len(self.object_list) == 0
        if is_empty:
            raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.")
                    % {'class_name': self.__class__.__name__})
    context = self.get_context_data()
    return self.render_to_response(context)

def get_allow_empty(

self)

Returns True if the view should display empty lists, and False if a 404 should be raised instead.

def get_allow_empty(self):
    """
    Returns ``True`` if the view should display empty lists, and ``False``
    if a 404 should be raised instead.
    """
    return self.allow_empty

def get_context_data(

self, *args, **kwargs)

def get_context_data(self, *args, **kwargs):
    context = super(GeoCountryItemView, self).get_context_data(*args, **kwargs)
    context['country'] = self.country
    context['continent'] =  self.continent
    context['count'] = self.object_list.count()
    return context

def get_context_object_name(

self, object_list)

Get the name of the item to be used in the context.

def get_context_object_name(self, object_list):
    """
    Get the name of the item to be used in the context.
    """
    if self.context_object_name:
        return self.context_object_name
    elif hasattr(object_list, 'model'):
        return '%s_list' % object_list.model._meta.model_name
    else:
        return None

def get_paginate_by(

self, queryset)

Get the number of items to paginate by, or None for no pagination.

def get_paginate_by(self, queryset):
    """
    Get the number of items to paginate by, or ``None`` for no pagination.
    """
    return self.paginate_by

def get_paginate_orphans(

self)

Returns the maximum number of orphans extend the last page by when paginating.

def get_paginate_orphans(self):
    """
    Returns the maximum number of orphans extend the last page by when
    paginating.
    """
    return self.paginate_orphans

def get_paginator(

self, queryset, per_page, orphans=0, allow_empty_first_page=True, **kwargs)

Return an instance of the paginator for this view.

def get_paginator(self, queryset, per_page, orphans=0,
                  allow_empty_first_page=True, **kwargs):
    """
    Return an instance of the paginator for this view.
    """
    return self.paginator_class(
        queryset, per_page, orphans=orphans,
        allow_empty_first_page=allow_empty_first_page, **kwargs)

def get_queryset(

self)

def get_queryset(self):
    country = self.kwargs['country']
    continent = self.kwargs['continent']
    self.continent = Location.objects.by_flatname(continent)[0]
    self.country = Location.objects.by_flatname(country)[0]
    return MediaItem.objects.enriched().by_location(self.country)

def get_template_names(

self)

Return a list of template names to be used for the request. Must return a list. May not be called if render_to_response is overridden.

def get_template_names(self):
    """
    Return a list of template names to be used for the request. Must return
    a list. May not be called if render_to_response is overridden.
    """
    try:
        names = super(MultipleObjectTemplateResponseMixin, self).get_template_names()
    except ImproperlyConfigured:
        # If template_name isn't specified, it's not a problem --
        # we just start with an empty list.
        names = []
    # If the list is a queryset, we'll invent a template name based on the
    # app and model name. This name gets put at the end of the template
    # name list so that user-supplied names override the automatically-
    # generated ones.
    if hasattr(self.object_list, 'model'):
        opts = self.object_list.model._meta
        names.append("%s/%s%s.html" % (opts.app_label, opts.model_name, self.template_name_suffix))
    return names

def http_method_not_allowed(

self, request, *args, **kwargs)

def http_method_not_allowed(self, request, *args, **kwargs):
    logger.warning('Method Not Allowed (%s): %s', request.method, request.path,
        extra={
            'status_code': 405,
            'request': self.request
        }
    )
    return http.HttpResponseNotAllowed(self._allowed_methods())

def options(

self, request, *args, **kwargs)

Handles responding to requests for the OPTIONS HTTP verb.

def options(self, request, *args, **kwargs):
    """
    Handles responding to requests for the OPTIONS HTTP verb.
    """
    response = http.HttpResponse()
    response['Allow'] = ', '.join(self._allowed_methods())
    response['Content-Length'] = '0'
    return response

def paginate_queryset(

self, queryset, page_size)

Paginate the queryset, if needed.

def paginate_queryset(self, queryset, page_size):
    """
    Paginate the queryset, if needed.
    """
    paginator = self.get_paginator(
        queryset, page_size, orphans=self.get_paginate_orphans(),
        allow_empty_first_page=self.get_allow_empty())
    page_kwarg = self.page_kwarg
    page = self.kwargs.get(page_kwarg) or self.request.GET.get(page_kwarg) or 1
    try:
        page_number = int(page)
    except ValueError:
        if page == 'last':
            page_number = paginator.num_pages
        else:
            raise Http404(_("Page is not 'last', nor can it be converted to an int."))
    try:
        page = paginator.page(page_number)
        return (paginator, page, page.object_list, page.has_other_pages())
    except InvalidPage as e:
        raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
                            'page_number': page_number,
                            'message': str(e)
        })

def render_to_response(

self, context, **response_kwargs)

Returns a response, using the response_class for this view, with a template rendered with the given context.

If any keyword arguments are provided, they will be passed to the constructor of the response class.

def render_to_response(self, context, **response_kwargs):
    """
    Returns a response, using the `response_class` for this
    view, with a template rendered with the given context.
    If any keyword arguments are provided, they will be
    passed to the constructor of the response class.
    """
    response_kwargs.setdefault('content_type', self.content_type)
    return self.response_class(
        request = self.request,
        template = self.get_template_names(),
        context = context,
        **response_kwargs
    )

class GeoView

Provide Geo web UI methods

class GeoView(object):
    """Provide Geo web UI methods"""

    def list_continents(self, request):
        continents = MediaItem.objects.all().countries(group_by_continent=True)
        return render(request, 'telemeta/geo_continents.html',
                    {'continents': continents, 'gmap_key': settings.TELEMETA_GMAP_KEY })

    def country_info(self, request, id):
        country = Location.objects.get(pk=id)
        return render(request, 'telemeta/country_info.html', {
            'country': country, 'continent': country.continents()[0]})

    def list_countries(self, request, continent):
        continent = Location.objects.by_flatname(continent)[0]
        countries = MediaItem.objects.by_location(continent).countries()

        return render(request, 'telemeta/geo_countries.html', {
            'continent': continent,
            'countries': countries
        })

    def list_country_collections(self, request, continent, country):
        continent = Location.objects.by_flatname(continent)[0]
        country = Location.objects.by_flatname(country)[0]
        objects = MediaCollection.objects.enriched().by_location(country)
        return list_detail.object_list(request, objects,
            template_name='telemeta/geo_country_collections.html', paginate_by=20,
            extra_context={'country': country, 'continent': continent})

    def list_country_items(self, request, continent, country):
        continent = Location.objects.by_flatname(continent)[0]
        country = Location.objects.by_flatname(country)[0]
        objects = MediaItem.objects.enriched().by_location(country)
        return list_detail.object_list(request, objects,
            template_name='telemeta/geo_country_items.html', paginate_by=20,
            extra_context={'country': country, 'continent': continent})

Ancestors (in MRO)

Methods

def country_info(

self, request, id)

def country_info(self, request, id):
    country = Location.objects.get(pk=id)
    return render(request, 'telemeta/country_info.html', {
        'country': country, 'continent': country.continents()[0]})

def list_continents(

self, request)

def list_continents(self, request):
    continents = MediaItem.objects.all().countries(group_by_continent=True)
    return render(request, 'telemeta/geo_continents.html',
                {'continents': continents, 'gmap_key': settings.TELEMETA_GMAP_KEY })

def list_countries(

self, request, continent)

def list_countries(self, request, continent):
    continent = Location.objects.by_flatname(continent)[0]
    countries = MediaItem.objects.by_location(continent).countries()
    return render(request, 'telemeta/geo_countries.html', {
        'continent': continent,
        'countries': countries
    })

def list_country_collections(

self, request, continent, country)

def list_country_collections(self, request, continent, country):
    continent = Location.objects.by_flatname(continent)[0]
    country = Location.objects.by_flatname(country)[0]
    objects = MediaCollection.objects.enriched().by_location(country)
    return list_detail.object_list(request, objects,
        template_name='telemeta/geo_country_collections.html', paginate_by=20,
        extra_context={'country': country, 'continent': continent})

def list_country_items(

self, request, continent, country)

def list_country_items(self, request, continent, country):
    continent = Location.objects.by_flatname(continent)[0]
    country = Location.objects.by_flatname(country)[0]
    objects = MediaItem.objects.enriched().by_location(country)
    return list_detail.object_list(request, objects,
        template_name='telemeta/geo_country_items.html', paginate_by=20,
        extra_context={'country': country, 'continent': continent})