Ticket #608: django-update.diff

File django-update.diff, 21.1 KB (added by scaba, 10 years ago)
  • django/views/generic/date_based.py

     
    1 from django.core import template_loader
    2 from django.core.exceptions import Http404, ObjectDoesNotExist
    3 from django.core.extensions import DjangoContext as Context
    4 from django.core.xheaders import populate_xheaders
    5 from django.models import get_module
    6 from django.utils.httpwrappers import HttpResponse
    7 import datetime, time
    8 
    9 def archive_index(request, app_label, module_name, date_field, num_latest=15,
    10                   template_name=None, template_loader=template_loader,
    11                   extra_lookup_kwargs={}, extra_context={}):
    12     """
    13     Generic top-level archive of date-based objects.
    14 
    15     Templates: ``<app_label>/<module_name>_archive``
    16     Context:
    17         date_list
    18             List of years
    19         latest
    20             Latest N (defaults to 15) objects by date
    21     """
    22     mod = get_module(app_label, module_name)
    23     lookup_kwargs = {'%s__lte' % date_field: datetime.datetime.now()}
    24     lookup_kwargs.update(extra_lookup_kwargs)
    25     date_list = getattr(mod, "get_%s_list" % date_field)('year', **lookup_kwargs)[::-1]
    26     if not date_list:
    27         raise Http404("No %s.%s available" % (app_label, module_name))
    28 
    29     if num_latest:
    30         lookup_kwargs.update({
    31             'limit': num_latest,
    32             'order_by': ('-' + date_field,),
    33         })
    34         latest = mod.get_list(**lookup_kwargs)
    35     else:
    36         latest = None
    37 
    38     if not template_name:
    39         template_name = "%s/%s_archive" % (app_label, module_name)
    40     t = template_loader.get_template(template_name)
    41     c = Context(request, {
    42         'date_list' : date_list,
    43         'latest' : latest,
    44     })
    45     for key, value in extra_context.items():
    46         if callable(value):
    47             c[key] = value()
    48         else:
    49             c[key] = value
    50     return HttpResponse(t.render(c))
    51 
    52 def archive_year(request, year, app_label, module_name, date_field,
    53                  template_name=None, template_loader=template_loader,
    54                  extra_lookup_kwargs={}, extra_context={}):
    55     """
    56     Generic yearly archive view.
    57 
    58     Templates: ``<app_label>/<module_name>_archive_year``
    59     Context:
    60         date_list
    61             List of months in this year with objects
    62         year
    63             This year
    64     """
    65     mod = get_module(app_label, module_name)
    66     now = datetime.datetime.now()
    67     lookup_kwargs = {'%s__year' % date_field: year}
    68     # Only bother to check current date if the year isn't in the past.
    69     if int(year) >= now.year:
    70         lookup_kwargs['%s__lte' % date_field] = now
    71     lookup_kwargs.update(extra_lookup_kwargs)
    72     date_list = getattr(mod, "get_%s_list" % date_field)('month', **lookup_kwargs)
    73     if not date_list:
    74         raise Http404
    75     if not template_name:
    76         template_name = "%s/%s_archive_year" % (app_label, module_name)
    77     t = template_loader.get_template(template_name)
    78     c = Context(request, {
    79         'date_list': date_list,
    80         'year': year,
    81     })
    82     for key, value in extra_context.items():
    83         if callable(value):
    84             c[key] = value()
    85         else:
    86             c[key] = value
    87     return HttpResponse(t.render(c))
    88 
    89 def archive_month(request, year, month, app_label, module_name, date_field,
    90                   month_format='%b', template_name=None, template_loader=template_loader,
    91                   extra_lookup_kwargs={}, extra_context={}):
    92     """
    93     Generic monthly archive view.
    94 
    95     Templates: ``<app_label>/<module_name>_archive_month``
    96     Context:
    97         month:
    98             this month
    99         object_list:
    100             list of objects published in the given month
    101     """
    102     try:
    103         date = datetime.date(*time.strptime(year+month, '%Y'+month_format)[:3])
    104     except ValueError:
    105         raise Http404
    106 
    107     mod = get_module(app_label, module_name)
    108     now = datetime.datetime.now()
    109     # Calculate first and last day of month, for use in a date-range lookup.
    110     first_day = date.replace(day=1)
    111     last_day = date
    112     for i in (31, 30, 29, 28):
    113         try:
    114             last_day = last_day.replace(day=i)
    115         except ValueError:
    116             continue
    117         else:
    118             break
    119     lookup_kwargs = {'%s__range' % date_field: (first_day, last_day)}
    120     # Only bother to check current date if the month isn't in the past.
    121     if last_day >= now.date():
    122         lookup_kwargs['%s__lte' % date_field] = now
    123     lookup_kwargs.update(extra_lookup_kwargs)
    124     object_list = mod.get_list(**lookup_kwargs)
    125     if not object_list:
    126         raise Http404
    127     if not template_name:
    128         template_name = "%s/%s_archive_month" % (app_label, module_name)
    129     t = template_loader.get_template(template_name)
    130     c = Context(request, {
    131         'object_list': object_list,
    132         'month': date,
    133     })
    134     for key, value in extra_context.items():
    135         if callable(value):
    136             c[key] = value()
    137         else:
    138             c[key] = value
    139     return HttpResponse(t.render(c))
    140 
    141 def archive_day(request, year, month, day, app_label, module_name, date_field,
    142                 month_format='%b', day_format='%d', template_name=None,
    143                 template_loader=template_loader, extra_lookup_kwargs={},
    144                 extra_context={}, allow_empty=False):
    145     """
    146     Generic daily archive view.
    147 
    148     Templates: ``<app_label>/<module_name>_archive_day``
    149     Context:
    150         object_list:
    151             list of objects published that day
    152         day:
    153             (datetime) the day
    154         previous_day
    155             (datetime) the previous day
    156         next_day
    157             (datetime) the next day, or None if the current day is today
    158     """
    159     try:
    160         date = datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3])
    161     except ValueError:
    162         raise Http404
    163 
    164     mod = get_module(app_label, module_name)
    165     now = datetime.datetime.now()
    166     lookup_kwargs = {
    167         '%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
    168     }
    169     # Only bother to check current date if the date isn't in the past.
    170     if date >= now.date():
    171         lookup_kwargs['%s__lte' % date_field] = now
    172     lookup_kwargs.update(extra_lookup_kwargs)
    173     object_list = mod.get_list(**lookup_kwargs)
    174     if not allow_empty and not object_list:
    175         raise Http404
    176     if not template_name:
    177         template_name = "%s/%s_archive_day" % (app_label, module_name)
    178     t = template_loader.get_template(template_name)
    179     c = Context(request, {
    180         'object_list': object_list,
    181         'day': date,
    182         'previous_day': date - datetime.timedelta(days=1),
    183         'next_day': (date < datetime.date.today()) and (date + datetime.timedelta(days=1)) or None,
    184     })
    185     for key, value in extra_context.items():
    186         if callable(value):
    187             c[key] = value()
    188         else:
    189             c[key] = value
    190     return HttpResponse(t.render(c))
    191 
    192 def archive_today(request, **kwargs):
    193     """
    194     Generic daily archive view for today. Same as archive_day view.
    195     """
    196     today = datetime.date.today()
    197     kwargs.update({
    198         'year': str(today.year),
    199         'month': today.strftime('%b').lower(),
    200         'day': str(today.day),
    201     })
    202     return archive_day(request, **kwargs)
    203 
    204 def object_detail(request, year, month, day, app_label, module_name, date_field,
    205                   month_format='%b', day_format='%d', object_id=None, slug=None,
    206                   slug_field=None, template_name=None, template_name_field=None,
    207                   template_loader=template_loader, extra_lookup_kwargs={},
    208                   extra_context={}):
    209     """
    210     Generic detail view from year/month/day/slug or year/month/day/id structure.
    211 
    212     Templates: ``<app_label>/<module_name>_detail``
    213     Context:
    214         object:
    215             the object to be detailed
    216     """
    217     try:
    218         date = datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3])
    219     except ValueError:
    220         raise Http404
    221 
    222     mod = get_module(app_label, module_name)
    223     now = datetime.datetime.now()
    224     lookup_kwargs = {
    225         '%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
    226     }
    227     # Only bother to check current date if the date isn't in the past.
    228     if date >= now.date():
    229         lookup_kwargs['%s__lte' % date_field] = now
    230     if object_id:
    231         lookup_kwargs['%s__exact' % mod.Klass._meta.pk.name] = object_id
    232     elif slug and slug_field:
    233         lookup_kwargs['%s__exact' % slug_field] = slug
    234     else:
    235         raise AttributeError("Generic detail view must be called with either an object_id or a slug/slugfield")
    236     lookup_kwargs.update(extra_lookup_kwargs)
    237     try:
    238         object = mod.get_object(**lookup_kwargs)
    239     except ObjectDoesNotExist:
    240         raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
    241     if not template_name:
    242         template_name = "%s/%s_detail" % (app_label, module_name)
    243     if template_name_field:
    244         template_name_list = [getattr(object, template_name_field), template_name]
    245         t = template_loader.select_template(template_name_list)
    246     else:
    247         t = template_loader.get_template(template_name)
    248     c = Context(request, {
    249         'object': object,
    250     })
    251     for key, value in extra_context.items():
    252         if callable(value):
    253             c[key] = value()
    254         else:
    255             c[key] = value
    256     response = HttpResponse(t.render(c))
    257     populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
    258     return response
     1from django.core import template_loader
     2from django.core.exceptions import Http404, ObjectDoesNotExist
     3from django.core.extensions import DjangoContext as Context
     4from django.core.xheaders import populate_xheaders
     5from django.models import get_module
     6from django.utils.httpwrappers import HttpResponse
     7import datetime, time
     8
     9def archive_index(request, app_label, module_name, date_field, num_latest=15,
     10                  template_name=None, template_loader=template_loader,
     11                  extra_lookup_kwargs={}, extra_context={}):
     12    """
     13    Generic top-level archive of date-based objects.
     14
     15    Templates: ``<app_label>/<module_name>_archive``
     16    Context:
     17        date_list
     18            List of years
     19        latest
     20            Latest N (defaults to 15) objects by date
     21    """
     22    mod = get_module(app_label, module_name)
     23    lookup_kwargs = {'%s__lte' % date_field: datetime.datetime.now()}
     24    lookup_kwargs.update(extra_lookup_kwargs)
     25    date_list = getattr(mod, "get_%s_list" % date_field)('year', **lookup_kwargs)[::-1]
     26    if not date_list:
     27        raise Http404("No %s.%s available" % (app_label, module_name))
     28
     29    if num_latest:
     30        lookup_kwargs.update({
     31            'limit': num_latest,
     32            'order_by': ('-' + date_field,),
     33        })
     34        latest = mod.get_list(**lookup_kwargs)
     35    else:
     36        latest = None
     37
     38    if not template_name:
     39        template_name = "%s/%s_archive" % (app_label, module_name)
     40    t = template_loader.get_template(template_name)
     41    c = Context(request, {
     42        'date_list' : date_list,
     43        'latest' : latest,
     44    })
     45    for key, value in extra_context.items():
     46        if callable(value):
     47            c[key] = value()
     48        else:
     49            c[key] = value
     50    return HttpResponse(t.render(c))
     51
     52def archive_year(request, year, app_label, module_name, date_field, future_ok=False,
     53                 template_name=None, template_loader=template_loader,
     54                 extra_lookup_kwargs={}, extra_context={}):
     55    """
     56    Generic yearly archive view.
     57
     58    Templates: ``<app_label>/<module_name>_archive_year``
     59    Context:
     60        date_list
     61            List of months in this year with objects
     62        year
     63            This year
     64    """
     65    mod = get_module(app_label, module_name)
     66    now = datetime.datetime.now()
     67    lookup_kwargs = {'%s__year' % date_field: year}
     68    # Only bother to check current date if the year isn't in the past.
     69    if int(year) >= now.year and not future_ok:
     70        lookup_kwargs['%s__lte' % date_field] = now
     71    lookup_kwargs.update(extra_lookup_kwargs)
     72    date_list = getattr(mod, "get_%s_list" % date_field)('month', **lookup_kwargs)
     73    if not date_list:
     74        raise Http404
     75    if not template_name:
     76        template_name = "%s/%s_archive_year" % (app_label, module_name)
     77    t = template_loader.get_template(template_name)
     78    c = Context(request, {
     79        'date_list': date_list,
     80        'year': year,
     81    })
     82    for key, value in extra_context.items():
     83        if callable(value):
     84            c[key] = value()
     85        else:
     86            c[key] = value
     87    return HttpResponse(t.render(c))
     88
     89def archive_month(request, year, month, app_label, module_name, date_field,
     90                  month_format='%b', future_ok=False, template_name=None, template_loader=template_loader,
     91                  extra_lookup_kwargs={}, extra_context={}):
     92    """
     93    Generic monthly archive view.
     94
     95    Templates: ``<app_label>/<module_name>_archive_month``
     96    Context:
     97        month:
     98            this month
     99        object_list:
     100            list of objects published in the given month
     101    """
     102    try:
     103        date = datetime.date(*time.strptime(year+month, '%Y'+month_format)[:3])
     104    except ValueError:
     105        raise Http404
     106
     107    mod = get_module(app_label, module_name)
     108    now = datetime.datetime.now()
     109    # Calculate first and last day of month, for use in a date-range lookup.
     110    first_day = date.replace(day=1)
     111    last_day = date
     112    for i in (31, 30, 29, 28):
     113        try:
     114            last_day = last_day.replace(day=i)
     115        except ValueError:
     116            continue
     117        else:
     118            break
     119    lookup_kwargs = {'%s__range' % date_field: (first_day, last_day)}
     120    # Only bother to check current date if the month isn't in the past.
     121    if last_day >= now.date() and not future_ok:
     122        lookup_kwargs['%s__lte' % date_field] = now
     123    lookup_kwargs.update(extra_lookup_kwargs)
     124    object_list = mod.get_list(**lookup_kwargs)
     125    if not object_list:
     126        raise Http404
     127    if not template_name:
     128        template_name = "%s/%s_archive_month" % (app_label, module_name)
     129    t = template_loader.get_template(template_name)
     130    c = Context(request, {
     131        'object_list': object_list,
     132        'month': date,
     133    })
     134    for key, value in extra_context.items():
     135        if callable(value):
     136            c[key] = value()
     137        else:
     138            c[key] = value
     139    return HttpResponse(t.render(c))
     140
     141def archive_day(request, year, month, day, app_label, module_name, date_field,
     142                month_format='%b', day_format='%d', future_ok=False, template_name=None,
     143                template_loader=template_loader, extra_lookup_kwargs={},
     144                extra_context={}, allow_empty=False):
     145    """
     146    Generic daily archive view.
     147
     148    Templates: ``<app_label>/<module_name>_archive_day``
     149    Context:
     150        object_list:
     151            list of objects published that day
     152        day:
     153            (datetime) the day
     154        previous_day
     155            (datetime) the previous day
     156        next_day
     157            (datetime) the next day, or None if the current day is today
     158    """
     159    try:
     160        date = datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3])
     161    except ValueError:
     162        raise Http404
     163
     164    mod = get_module(app_label, module_name)
     165    now = datetime.datetime.now()
     166    lookup_kwargs = {
     167        '%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
     168    }
     169    # Only bother to check current date if the date isn't in the past.
     170    if date >= now.date() and not future_ok:
     171        lookup_kwargs['%s__lte' % date_field] = now
     172    lookup_kwargs.update(extra_lookup_kwargs)
     173    object_list = mod.get_list(**lookup_kwargs)
     174    if not allow_empty and not object_list:
     175        raise Http404
     176    if not template_name:
     177        template_name = "%s/%s_archive_day" % (app_label, module_name)
     178    t = template_loader.get_template(template_name)
     179    c = Context(request, {
     180        'object_list': object_list,
     181        'day': date,
     182        'previous_day': date - datetime.timedelta(days=1),
     183        'next_day': (date < datetime.date.today()) and (date + datetime.timedelta(days=1)) or None,
     184    })
     185    for key, value in extra_context.items():
     186        if callable(value):
     187            c[key] = value()
     188        else:
     189            c[key] = value
     190    return HttpResponse(t.render(c))
     191
     192def archive_today(request, **kwargs):
     193    """
     194    Generic daily archive view for today. Same as archive_day view.
     195    """
     196    today = datetime.date.today()
     197    kwargs.update({
     198        'year': str(today.year),
     199        'month': today.strftime('%b').lower(),
     200        'day': str(today.day),
     201    })
     202    return archive_day(request, **kwargs)
     203
     204def object_detail(request, year, month, day, app_label, module_name, date_field,
     205                  month_format='%b', day_format='%d', object_id=None, slug=None,
     206                  slug_field=None, future_ok=False, template_name=None, template_name_field=None,
     207                  template_loader=template_loader, extra_lookup_kwargs={},
     208                  extra_context={}):
     209    """
     210    Generic detail view from year/month/day/slug or year/month/day/id structure.
     211
     212    Templates: ``<app_label>/<module_name>_detail``
     213    Context:
     214        object:
     215            the object to be detailed
     216    """
     217    try:
     218        date = datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3])
     219    except ValueError:
     220        raise Http404
     221
     222    mod = get_module(app_label, module_name)
     223    now = datetime.datetime.now()
     224    lookup_kwargs = {
     225        '%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max)),
     226    }
     227    # Only bother to check current date if the date isn't in the past.
     228    if date >= now.date() and not future_ok:
     229        lookup_kwargs['%s__lte' % date_field] = now
     230    if object_id:
     231        lookup_kwargs['%s__exact' % mod.Klass._meta.pk.name] = object_id
     232    elif slug and slug_field:
     233        lookup_kwargs['%s__exact' % slug_field] = slug
     234    else:
     235        raise AttributeError("Generic detail view must be called with either an object_id or a slug/slugfield")
     236    lookup_kwargs.update(extra_lookup_kwargs)
     237    try:
     238        object = mod.get_object(**lookup_kwargs)
     239    except ObjectDoesNotExist:
     240        raise Http404("%s.%s does not exist for %s" % (app_label, module_name, lookup_kwargs))
     241    if not template_name:
     242        template_name = "%s/%s_detail" % (app_label, module_name)
     243    if template_name_field:
     244        template_name_list = [getattr(object, template_name_field), template_name]
     245        t = template_loader.select_template(template_name_list)
     246    else:
     247        t = template_loader.get_template(template_name)
     248    c = Context(request, {
     249        'object': object,
     250    })
     251    for key, value in extra_context.items():
     252        if callable(value):
     253            c[key] = value()
     254        else:
     255            c[key] = value
     256    response = HttpResponse(t.render(c))
     257    populate_xheaders(request, response, app_label, module_name, getattr(object, object._meta.pk.name))
     258    return response
     259
     260def upcoming_index(request, app_label, module_name, date_field, num_upcoming=15,
     261                  template_name=None, template_loader=template_loader,
     262                  extra_lookup_kwargs={}, extra_context={}):
     263    """
     264    Index of future/upcoming date-based objects.
     265
     266    Templates: ``<app_label>/<module_name>_upcoming``
     267    Context:
     268        date_list
     269            List of years
     270        upcoming
     271            Next N (defaults to 15) upcoming objects by date
     272    """
     273    mod = get_module(app_label, module_name)
     274    lookup_kwargs = {'%s__gte' % date_field: datetime.datetime.now()}
     275    lookup_kwargs.update(extra_lookup_kwargs)
     276    date_list = getattr(mod, "get_%s_list" % date_field)('year', **lookup_kwargs)[::-1]
     277    if not date_list:
     278        raise Http404("No %s.%s available" % (app_label, module_name))
     279
     280    if num_upcoming:
     281        lookup_kwargs.update({
     282            'limit': num_upcoming,
     283            'order_by': (date_field,),
     284        })
     285        upcoming = mod.get_list(**lookup_kwargs)
     286    else:
     287        upcoming = None
     288
     289    if not template_name:
     290        template_name = "%s/%s_upcoming" % (app_label, module_name)
     291    t = template_loader.get_template(template_name)
     292    c = Context(request, {
     293        'date_list' : date_list,
     294        'upcoming' : upcoming,
     295    })
     296    for key, value in extra_context.items():
     297        if callable(value):
     298            c[key] = value()
     299        else:
     300            c[key] = value
     301    return HttpResponse(t.render(c))
Back to Top