django1/django/contrib/databrowse/plugins/calendars.py

148 lines
5.7 KiB
Python

from __future__ import unicode_literals
from django import http
from django.db import models
from django.contrib.databrowse.datastructures import EasyModel
from django.contrib.databrowse.sites import DatabrowsePlugin
from django.shortcuts import render_to_response
from django.utils.html import format_html, format_html_join
from django.utils.text import capfirst
from django.utils.encoding import force_text
from django.views.generic import dates
from django.utils import datetime_safe
class DateViewMixin(object):
allow_empty = False
allow_future = True
root_url = None
model = None
field = None
def get_context_data(self, **kwargs):
context = super(DateViewMixin, self).get_context_data(**kwargs)
context.update({
'root_url': self.root_url,
'model': self.model,
'field': self.field
})
return context
class DayView(DateViewMixin, dates.DayArchiveView):
template_name = 'databrowse/calendar_day.html'
class MonthView(DateViewMixin, dates.MonthArchiveView):
template_name = 'databrowse/calendar_month.html'
class YearView(DateViewMixin, dates.YearArchiveView):
template_name = 'databrowse/calendar_year.html'
class IndexView(DateViewMixin, dates.ArchiveIndexView):
template_name = 'databrowse/calendar_main.html'
class CalendarPlugin(DatabrowsePlugin):
def __init__(self, field_names=None):
self.field_names = field_names
def field_dict(self, model):
"""
Helper function that returns a dictionary of all DateFields or
DateTimeFields in the given model. If self.field_names is set, it takes
take that into account when building the dictionary.
"""
if self.field_names is None:
return dict([(f.name, f) for f in model._meta.fields if isinstance(f, models.DateField)])
else:
return dict([(f.name, f) for f in model._meta.fields if isinstance(f, models.DateField) and f.name in self.field_names])
def model_index_html(self, request, model, site):
fields = self.field_dict(model)
if not fields:
return ''
return format_html('<p class="filter"><strong>View calendar by:</strong> {0}</p>',
format_html_join(', ', '<a href="calendars/{0}/">{1}</a>',
((f.name, force_text(capfirst(f.verbose_name))) for f in fields.values())))
def urls(self, plugin_name, easy_instance_field):
if isinstance(easy_instance_field.field, models.DateField):
d = easy_instance_field.raw_value
return ['%s%s/%s/%s/%s/%s/' % (
easy_instance_field.model.url(),
plugin_name, easy_instance_field.field.name,
str(d.year),
datetime_safe.new_date(d).strftime('%b').lower(),
d.day)]
def model_view(self, request, model_databrowse, url):
self.model, self.site = model_databrowse.model, model_databrowse.site
self.fields = self.field_dict(self.model)
# If the model has no DateFields, there's no point in going further.
if not self.fields:
raise http.Http404('The requested model has no calendars.')
if url is None:
return self.homepage_view(request)
url_bits = url.split('/')
if url_bits[0] in self.fields:
return self.calendar_view(request, self.fields[url_bits[0]], *url_bits[1:])
raise http.Http404('The requested page does not exist.')
def homepage_view(self, request):
easy_model = EasyModel(self.site, self.model)
field_list = list(self.fields.values())
field_list.sort(key=lambda k:k.verbose_name)
return render_to_response('databrowse/calendar_homepage.html', {
'root_url': self.site.root_url,
'model': easy_model,
'field_list': field_list
})
def calendar_view(self, request, field, year=None, month=None, day=None):
easy_model = EasyModel(self.site, self.model)
root_url = self.site.root_url
if day is not None:
return DayView.as_view(
year=year, month=month, day=day,
date_field=field.name,
queryset=easy_model.get_query_set(),
root_url=root_url,
model=easy_model,
field=field
)(request)
elif month is not None:
return MonthView.as_view(
year=year, month=month,
date_field=field.name,
queryset=easy_model.get_query_set(),
root_url=root_url,
model=easy_model,
field=field
)(request)
elif year is not None:
return YearView.as_view(
year=year,
date_field=field.name,
queryset=easy_model.get_query_set(),
root_url=root_url,
model=easy_model,
field=field
)(request)
else:
return IndexView.as_view(
date_field=field.name,
queryset=easy_model.get_query_set(),
root_url=root_url,
model=easy_model,
field=field
)(request)
assert False, ('%s, %s, %s, %s' % (field, year, month, day))