| 1 | from django.template import loader, RequestContext |
|---|
| 2 | from django.core.exceptions import ObjectDoesNotExist |
|---|
| 3 | from django.core.xheaders import populate_xheaders |
|---|
| 4 | #from django.db.models.fields import DateTimeField |
|---|
| 5 | from google.appengine.ext.db import DateTimeProperty |
|---|
| 6 | from django.http import Http404, HttpResponse |
|---|
| 7 | import datetime, time |
|---|
| 8 | |
|---|
| 9 | from gae_django.utils.timezoneutil import utctolocal, localtoutc |
|---|
| 10 | |
|---|
| 11 | from django.conf import settings |
|---|
| 12 | import pytz |
|---|
| 13 | from sets import Set |
|---|
| 14 | |
|---|
| 15 | def archive_index(request, queryset, date_field, num_latest=15, |
|---|
| 16 | template_name=None, template_loader=loader, |
|---|
| 17 | extra_context=None, allow_empty=False, context_processors=None, |
|---|
| 18 | mimetype=None, allow_future=False): |
|---|
| 19 | """ |
|---|
| 20 | Generic top-level archive of date-based objects. |
|---|
| 21 | |
|---|
| 22 | Templates: ``<app_label>/<model_name>_archive.html`` |
|---|
| 23 | Context: |
|---|
| 24 | date_list |
|---|
| 25 | List of years |
|---|
| 26 | latest |
|---|
| 27 | Latest N (defaults to 15) objects by date |
|---|
| 28 | """ |
|---|
| 29 | if extra_context is None: extra_context = {} |
|---|
| 30 | model = queryset._model_class |
|---|
| 31 | if not allow_future: |
|---|
| 32 | queryset = queryset.filter('%s <=' % date_field, datetime.datetime.now()) |
|---|
| 33 | #queryset = queryset.filter(**{'%s__lte' % date_field: datetime.datetime.now()}) |
|---|
| 34 | #date_list = queryset.dates(date_field, 'year')[::-1] |
|---|
| 35 | if isinstance(model.fields()[date_field], DateTimeProperty): |
|---|
| 36 | date_list = list(Set([datetime.datetime(utctolocal(q.created).year, 1, 1) |
|---|
| 37 | for q in queryset])) |
|---|
| 38 | else: |
|---|
| 39 | date_list = list(Set([datetime.datetime(q.created.year, 1, 1) for q in queryset])) |
|---|
| 40 | date_list.sort(reverse=True) |
|---|
| 41 | if not date_list and not allow_empty: |
|---|
| 42 | #raise Http404, "No %s available" % model._meta.verbose_name |
|---|
| 43 | raise Http404, "No %s available" % date_field |
|---|
| 44 | |
|---|
| 45 | if date_list and num_latest: |
|---|
| 46 | #latest = queryset.order_by('-'+date_field)[:num_latest] |
|---|
| 47 | latest = queryset.order('-'+date_field)[0:num_latest] |
|---|
| 48 | else: |
|---|
| 49 | latest = None |
|---|
| 50 | |
|---|
| 51 | if not template_name: |
|---|
| 52 | raise Http404, "template is not defined" |
|---|
| 53 | #template_name = "%s/%s_archive.html" % (model._meta.app_label, model._meta.object_name.lower()) |
|---|
| 54 | t = template_loader.get_template(template_name) |
|---|
| 55 | c = RequestContext(request, { |
|---|
| 56 | 'date_list' : date_list, |
|---|
| 57 | 'latest' : latest, |
|---|
| 58 | }, context_processors) |
|---|
| 59 | for key, value in extra_context.items(): |
|---|
| 60 | if callable(value): |
|---|
| 61 | c[key] = value() |
|---|
| 62 | else: |
|---|
| 63 | c[key] = value |
|---|
| 64 | return HttpResponse(t.render(c), mimetype=mimetype) |
|---|
| 65 | |
|---|
| 66 | def archive_year(request, year, queryset, date_field, template_name=None, |
|---|
| 67 | template_loader=loader, extra_context=None, allow_empty=False, |
|---|
| 68 | context_processors=None, template_object_name='object', mimetype=None, |
|---|
| 69 | make_object_list=False, allow_future=False): |
|---|
| 70 | """ |
|---|
| 71 | Generic yearly archive view. |
|---|
| 72 | |
|---|
| 73 | Templates: ``<app_label>/<model_name>_archive_year.html`` |
|---|
| 74 | Context: |
|---|
| 75 | date_list |
|---|
| 76 | List of months in this year with objects |
|---|
| 77 | year |
|---|
| 78 | This year |
|---|
| 79 | object_list |
|---|
| 80 | List of objects published in the given month |
|---|
| 81 | (Only available if make_object_list argument is True) |
|---|
| 82 | """ |
|---|
| 83 | year = int(year) |
|---|
| 84 | if extra_context is None: extra_context = {} |
|---|
| 85 | #model = queryset.model |
|---|
| 86 | now = datetime.datetime.now() |
|---|
| 87 | |
|---|
| 88 | #lookup_kwargs = {'%s__year' % date_field: year} |
|---|
| 89 | mindate = datetime.datetime( |
|---|
| 90 | year, 1, 1, tzinfo=pytz.timezone(settings.TIME_ZONE) |
|---|
| 91 | ).astimezone(pytz.utc) |
|---|
| 92 | maxdate = datetime.datetime( |
|---|
| 93 | int(year)+1, 1, 1, tzinfo=pytz.timezone(settings.TIME_ZONE) |
|---|
| 94 | ).astimezone(pytz.utc) - datetime.timedelta(1) |
|---|
| 95 | lookup_args = [('%s >='% date_field, datetime.datetime(*mindate.timetuple()[:6]),), |
|---|
| 96 | ('%s <' % date_field, datetime.datetime(*maxdate.timetuple()[:6]),) |
|---|
| 97 | ] |
|---|
| 98 | |
|---|
| 99 | # Only bother to check current date if the year isn't in the past and future objects aren't requested. |
|---|
| 100 | if int(year) >= now.year and not allow_future: |
|---|
| 101 | lookup_args.append(('%s <=' % date_field, now,)) |
|---|
| 102 | #lookup_args.append('%s__lte' % date_field] = now |
|---|
| 103 | #date_list = queryset.filter(**lookup_kwargs).dates(date_field, 'month') |
|---|
| 104 | for property_operator, value in lookup_args: |
|---|
| 105 | queryset.filter(property_operator, value) |
|---|
| 106 | date_list = list(Set( |
|---|
| 107 | #[datetime.datetime(q.created.replace(tzinfo=pytz.utc).astimezone(pytz.timezone(settings.TIME_ZONE)).year, q.created.month, 1) |
|---|
| 108 | [datetime.datetime(utctolocal(q.created).year, utctolocal(q.created).month, 1) |
|---|
| 109 | for q in queryset] |
|---|
| 110 | )) |
|---|
| 111 | if not date_list and not allow_empty: |
|---|
| 112 | raise Http404 |
|---|
| 113 | if make_object_list: |
|---|
| 114 | #object_list = queryset.filter(**lookup_kwargs).order_by(date_field) |
|---|
| 115 | object_list = queryset.order(date_field) |
|---|
| 116 | else: |
|---|
| 117 | object_list = [] |
|---|
| 118 | if not template_name: |
|---|
| 119 | raise Http404, "template is not defined" |
|---|
| 120 | #template_name = "%s/%s_archive_year.html" % (model._meta.app_label, model._meta.object_name.lower()) |
|---|
| 121 | t = template_loader.get_template(template_name) |
|---|
| 122 | c = RequestContext(request, { |
|---|
| 123 | 'date_list': date_list, |
|---|
| 124 | 'year': year, |
|---|
| 125 | '%s_list' % template_object_name: object_list, |
|---|
| 126 | }, context_processors) |
|---|
| 127 | for key, value in extra_context.items(): |
|---|
| 128 | if callable(value): |
|---|
| 129 | c[key] = value() |
|---|
| 130 | else: |
|---|
| 131 | c[key] = value |
|---|
| 132 | return HttpResponse(t.render(c), mimetype=mimetype) |
|---|
| 133 | |
|---|
| 134 | def archive_month(request, year, month, queryset, date_field, |
|---|
| 135 | month_format='%b', template_name=None, template_loader=loader, |
|---|
| 136 | extra_context=None, allow_empty=False, context_processors=None, |
|---|
| 137 | template_object_name='object', mimetype=None, allow_future=False): |
|---|
| 138 | """ |
|---|
| 139 | Generic monthly archive view. |
|---|
| 140 | |
|---|
| 141 | Templates: ``<app_label>/<model_name>_archive_month.html`` |
|---|
| 142 | Context: |
|---|
| 143 | month: |
|---|
| 144 | (date) this month |
|---|
| 145 | next_month: |
|---|
| 146 | (date) the first day of the next month, or None if the next month is in the future |
|---|
| 147 | previous_month: |
|---|
| 148 | (date) the first day of the previous month |
|---|
| 149 | object_list: |
|---|
| 150 | list of objects published in the given month |
|---|
| 151 | """ |
|---|
| 152 | if extra_context is None: extra_context = {} |
|---|
| 153 | try: |
|---|
| 154 | #date = datetime.date(*time.strptime(year+month, '%Y'+month_format)[:3]) |
|---|
| 155 | date = datetime.datetime(*time.strptime(year+month, '%Y'+month_format)[:3]) |
|---|
| 156 | except ValueError: |
|---|
| 157 | raise Http404 |
|---|
| 158 | |
|---|
| 159 | #model = queryset.model |
|---|
| 160 | now = datetime.datetime.now() |
|---|
| 161 | |
|---|
| 162 | # Calculate first and last day of month, for use in a date-range lookup. |
|---|
| 163 | first_day = date.replace(day=1) |
|---|
| 164 | if first_day.month == 12: |
|---|
| 165 | last_day = first_day.replace(year=first_day.year + 1, month=1) |
|---|
| 166 | else: |
|---|
| 167 | last_day = first_day.replace(month=first_day.month + 1) |
|---|
| 168 | last_day = localtoutc(last_day) |
|---|
| 169 | #lookup_kwargs = {'%s__range' % date_field: (first_day, last_day)} |
|---|
| 170 | lookup_args = [('%s >=' % date_field, first_day,), ('%s <' % date_field, last_day,)] |
|---|
| 171 | |
|---|
| 172 | # Only bother to check current date if the month isn't in the past and future objects are requested. |
|---|
| 173 | #if last_day >= now.date() and not allow_future: |
|---|
| 174 | if last_day >= now and not allow_future: |
|---|
| 175 | #lookup_kwargs['%s__lte' % date_field] = now |
|---|
| 176 | lookup_args.append(('%s <=' % date_field, now,)) |
|---|
| 177 | #object_list = queryset.filter(**lookup_kwargs) |
|---|
| 178 | for property_operator, value in lookup_args: |
|---|
| 179 | queryset.filter(property_operator, value) |
|---|
| 180 | object_list = queryset |
|---|
| 181 | if not object_list and not allow_empty: |
|---|
| 182 | raise Http404 |
|---|
| 183 | |
|---|
| 184 | # Calculate the next month, if applicable. |
|---|
| 185 | if allow_future: |
|---|
| 186 | next_month = last_day + datetime.timedelta(days=1) |
|---|
| 187 | #elif last_day < datetime.date.today(): |
|---|
| 188 | elif last_day < datetime.datetime.today(): |
|---|
| 189 | next_month = last_day + datetime.timedelta(days=1) |
|---|
| 190 | else: |
|---|
| 191 | next_month = None |
|---|
| 192 | |
|---|
| 193 | if not template_name: |
|---|
| 194 | raise Http404, "template is not defined" |
|---|
| 195 | #template_name = "%s/%s_archive_month.html" % (model._meta.app_label, model._meta.object_name.lower()) |
|---|
| 196 | t = template_loader.get_template(template_name) |
|---|
| 197 | c = RequestContext(request, { |
|---|
| 198 | '%s_list' % template_object_name: object_list, |
|---|
| 199 | 'month': date, |
|---|
| 200 | 'next_month': next_month, |
|---|
| 201 | 'previous_month': first_day - datetime.timedelta(days=1), |
|---|
| 202 | }, context_processors) |
|---|
| 203 | for key, value in extra_context.items(): |
|---|
| 204 | if callable(value): |
|---|
| 205 | c[key] = value() |
|---|
| 206 | else: |
|---|
| 207 | c[key] = value |
|---|
| 208 | return HttpResponse(t.render(c), mimetype=mimetype) |
|---|
| 209 | |
|---|
| 210 | def archive_week(request, year, week, queryset, date_field, |
|---|
| 211 | template_name=None, template_loader=loader, |
|---|
| 212 | extra_context=None, allow_empty=True, context_processors=None, |
|---|
| 213 | template_object_name='object', mimetype=None, allow_future=False): |
|---|
| 214 | """ |
|---|
| 215 | Generic weekly archive view. |
|---|
| 216 | |
|---|
| 217 | Templates: ``<app_label>/<model_name>_archive_week.html`` |
|---|
| 218 | Context: |
|---|
| 219 | week: |
|---|
| 220 | (date) this week |
|---|
| 221 | object_list: |
|---|
| 222 | list of objects published in the given week |
|---|
| 223 | """ |
|---|
| 224 | if extra_context is None: extra_context = {} |
|---|
| 225 | try: |
|---|
| 226 | #date = datetime.date(*time.strptime(year+'-0-'+week, '%Y-%w-%U')[:3]) |
|---|
| 227 | date = datetime.datetime(*time.strptime(year+'-0-'+week, '%Y-%w-%U')[:3]) |
|---|
| 228 | except ValueError: |
|---|
| 229 | raise Http404 |
|---|
| 230 | |
|---|
| 231 | #model = queryset.model |
|---|
| 232 | now = datetime.datetime.now() |
|---|
| 233 | |
|---|
| 234 | # Calculate first and last day of week, for use in a date-range lookup. |
|---|
| 235 | first_day = localtoutc(date) |
|---|
| 236 | last_day = localtoutc(date + datetime.timedelta(days=7)) |
|---|
| 237 | #lookup_kwargs = {'%s__range' % date_field: (first_day, last_day)} |
|---|
| 238 | lookup_args = [('%s >=' % date_field, first_day,), ('%s <' % date_field, last_day,)] |
|---|
| 239 | |
|---|
| 240 | # Only bother to check current date if the week isn't in the past and future objects aren't requested. |
|---|
| 241 | #if last_day >= now.date() and not allow_future: |
|---|
| 242 | if last_day >= now and not allow_future: |
|---|
| 243 | #lookup_kwargs['%s__lte' % date_field] = now |
|---|
| 244 | lookup_args.append(('%s <=' % date_field, now,)) |
|---|
| 245 | #object_list = queryset.filter(**lookup_kwargs) |
|---|
| 246 | for property_operator, value in lookup_args: |
|---|
| 247 | queryset.filter(property_operator, value) |
|---|
| 248 | object_list = queryset |
|---|
| 249 | if not object_list and not allow_empty: |
|---|
| 250 | raise Http404 |
|---|
| 251 | if not template_name: |
|---|
| 252 | #template_name = "%s/%s_archive_week.html" % (model._meta.app_label, model._meta.object_name.lower()) |
|---|
| 253 | raise Http404, "template is not defined" |
|---|
| 254 | t = template_loader.get_template(template_name) |
|---|
| 255 | c = RequestContext(request, { |
|---|
| 256 | '%s_list' % template_object_name: object_list, |
|---|
| 257 | 'week': date, |
|---|
| 258 | }) |
|---|
| 259 | for key, value in extra_context.items(): |
|---|
| 260 | if callable(value): |
|---|
| 261 | c[key] = value() |
|---|
| 262 | else: |
|---|
| 263 | c[key] = value |
|---|
| 264 | return HttpResponse(t.render(c), mimetype=mimetype) |
|---|
| 265 | |
|---|
| 266 | def archive_day(request, year, month, day, queryset, date_field, |
|---|
| 267 | month_format='%b', day_format='%d', template_name=None, |
|---|
| 268 | template_loader=loader, extra_context=None, allow_empty=False, |
|---|
| 269 | context_processors=None, template_object_name='object', |
|---|
| 270 | mimetype=None, allow_future=False): |
|---|
| 271 | """ |
|---|
| 272 | Generic daily archive view. |
|---|
| 273 | |
|---|
| 274 | Templates: ``<app_label>/<model_name>_archive_day.html`` |
|---|
| 275 | Context: |
|---|
| 276 | object_list: |
|---|
| 277 | list of objects published that day |
|---|
| 278 | day: |
|---|
| 279 | (datetime) the day |
|---|
| 280 | previous_day |
|---|
| 281 | (datetime) the previous day |
|---|
| 282 | next_day |
|---|
| 283 | (datetime) the next day, or None if the current day is today |
|---|
| 284 | """ |
|---|
| 285 | if extra_context is None: extra_context = {} |
|---|
| 286 | try: |
|---|
| 287 | #date = datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3]) |
|---|
| 288 | date = datetime.datetime(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3]) |
|---|
| 289 | except ValueError: |
|---|
| 290 | raise Http404 |
|---|
| 291 | |
|---|
| 292 | #model = queryset.model |
|---|
| 293 | model = queryset._model_class |
|---|
| 294 | now = datetime.datetime.now() |
|---|
| 295 | |
|---|
| 296 | #if isinstance(model._meta.get_field(date_field), DateTimeField): |
|---|
| 297 | if isinstance(model.fields()[date_field], DateTimeProperty): |
|---|
| 298 | pass |
|---|
| 299 | #lookup_kwargs = {'%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max))} |
|---|
| 300 | else: |
|---|
| 301 | #lookup_args = {date_field: date} |
|---|
| 302 | #lookup_args = [('%s =' % date_field, date,)] |
|---|
| 303 | date = datetime.datetime(*date.timetuple()[:3]) |
|---|
| 304 | min = localtoutc(datetime.datetime.combine(date, datetime.time.min)) |
|---|
| 305 | max = localtoutc(datetime.datetime.combine(date, datetime.time.max)) |
|---|
| 306 | #lookup_args = [('%s >=' % date_field, datetime.datetime.combine(date, datetime.time.min),), |
|---|
| 307 | # ('%s <' % date_field, datetime.datetime.combine(date, datetime.time.max),)] |
|---|
| 308 | lookup_args = [('%s >=' % date_field, min,), ('%s <' % date_field, max,)] |
|---|
| 309 | |
|---|
| 310 | # Only bother to check current date if the date isn't in the past and future objects aren't requested. |
|---|
| 311 | #if date >= now.date() and not allow_future: |
|---|
| 312 | if date >= now and not allow_future: |
|---|
| 313 | #lookup_kwargs['%s__lte' % date_field] = now |
|---|
| 314 | lookup_args.append(('%s <=' % date_field, now,)) |
|---|
| 315 | #object_list = queryset.filter(**lookup_kwargs) |
|---|
| 316 | for property_operator, value in lookup_args: |
|---|
| 317 | queryset.filter(property_operator, value) |
|---|
| 318 | object_list = queryset |
|---|
| 319 | if not allow_empty and not object_list: |
|---|
| 320 | raise Http404 |
|---|
| 321 | |
|---|
| 322 | # Calculate the next day, if applicable. |
|---|
| 323 | if allow_future: |
|---|
| 324 | next_day = date + datetime.timedelta(days=1) |
|---|
| 325 | #elif date < datetime.date.today(): |
|---|
| 326 | elif date < datetime.datetime.today(): |
|---|
| 327 | next_day = date + datetime.timedelta(days=1) |
|---|
| 328 | else: |
|---|
| 329 | next_day = None |
|---|
| 330 | |
|---|
| 331 | if not template_name: |
|---|
| 332 | #template_name = "%s/%s_archive_day.html" % (model._meta.app_label, model._meta.object_name.lower()) |
|---|
| 333 | raise Http404, "template is not defined" |
|---|
| 334 | t = template_loader.get_template(template_name) |
|---|
| 335 | c = RequestContext(request, { |
|---|
| 336 | '%s_list' % template_object_name: object_list, |
|---|
| 337 | 'day': date, |
|---|
| 338 | 'previous_day': date - datetime.timedelta(days=1), |
|---|
| 339 | 'next_day': next_day, |
|---|
| 340 | }, context_processors) |
|---|
| 341 | for key, value in extra_context.items(): |
|---|
| 342 | if callable(value): |
|---|
| 343 | c[key] = value() |
|---|
| 344 | else: |
|---|
| 345 | c[key] = value |
|---|
| 346 | return HttpResponse(t.render(c), mimetype=mimetype) |
|---|
| 347 | |
|---|
| 348 | def archive_today(request, **kwargs): |
|---|
| 349 | """ |
|---|
| 350 | Generic daily archive view for today. Same as archive_day view. |
|---|
| 351 | """ |
|---|
| 352 | #today = datetime.date.today() |
|---|
| 353 | now = localtoutc(datetime.datetime.now(tz=pytz.timezone(settings.TIME_ZONE))) |
|---|
| 354 | kwargs.update({ |
|---|
| 355 | 'year': str(now.year), |
|---|
| 356 | 'month': now.strftime('%b').lower(), |
|---|
| 357 | 'day': str(now.day), |
|---|
| 358 | }) |
|---|
| 359 | return archive_day(request, **kwargs) |
|---|
| 360 | |
|---|
| 361 | ''' |
|---|
| 362 | def object_detail(request, year, month, day, queryset, date_field, |
|---|
| 363 | month_format='%b', day_format='%d', object_id=None, slug=None, |
|---|
| 364 | slug_field=None, template_name=None, template_name_field=None, |
|---|
| 365 | template_loader=loader, extra_context=None, context_processors=None, |
|---|
| 366 | template_object_name='object', mimetype=None, allow_future=False): |
|---|
| 367 | """ |
|---|
| 368 | Generic detail view from year/month/day/slug or year/month/day/id structure. |
|---|
| 369 | |
|---|
| 370 | Templates: ``<app_label>/<model_name>_detail.html`` |
|---|
| 371 | Context: |
|---|
| 372 | object: |
|---|
| 373 | the object to be detailed |
|---|
| 374 | """ |
|---|
| 375 | if extra_context is None: extra_context = {} |
|---|
| 376 | try: |
|---|
| 377 | date = datetime.date(*time.strptime(year+month+day, '%Y'+month_format+day_format)[:3]) |
|---|
| 378 | except ValueError: |
|---|
| 379 | raise Http404 |
|---|
| 380 | |
|---|
| 381 | model = queryset.model |
|---|
| 382 | now = datetime.datetime.now() |
|---|
| 383 | |
|---|
| 384 | #if isinstance(model._meta.get_field(date_field), DateTimeField): |
|---|
| 385 | # lookup_kwargs = {'%s__range' % date_field: (datetime.datetime.combine(date, datetime.time.min), datetime.datetime.combine(date, datetime.time.max))} |
|---|
| 386 | #else: |
|---|
| 387 | # lookup_kwargs = {date_field: date} |
|---|
| 388 | if isinstance(model.fields()[date_field], DateTimeProperty): |
|---|
| 389 | lookup_args = [('%s >=' % date_field, datetime.datetime.combine(date, datetime.time.min),), |
|---|
| 390 | ('%s <' % date_field, datetime.datetime.combine(date, datetime.time.max),)] |
|---|
| 391 | else: |
|---|
| 392 | lookup_args = [('%s =' % date_field, date,)] |
|---|
| 393 | |
|---|
| 394 | # Only bother to check current date if the date isn't in the past and future objects aren't requested. |
|---|
| 395 | #if date >= now.date() and not allow_future: |
|---|
| 396 | if date >= now and not allow_future: |
|---|
| 397 | #lookup_kwargs['%s__lte' % date_field] = now |
|---|
| 398 | lookup_args.append(('%s >=' % date_field, now,)) |
|---|
| 399 | if object_id: |
|---|
| 400 | lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id |
|---|
| 401 | lookup_kwargs['%s__exact' % model._meta.pk.name] = object_id |
|---|
| 402 | elif slug and slug_field: |
|---|
| 403 | lookup_kwargs['%s__exact' % slug_field] = slug |
|---|
| 404 | else: |
|---|
| 405 | raise AttributeError, "Generic detail view must be called with either an object_id or a slug/slugfield" |
|---|
| 406 | try: |
|---|
| 407 | obj = queryset.get(**lookup_kwargs) |
|---|
| 408 | except ObjectDoesNotExist: |
|---|
| 409 | raise Http404, "No %s found for" % model._meta.verbose_name |
|---|
| 410 | if not template_name: |
|---|
| 411 | template_name = "%s/%s_detail.html" % (model._meta.app_label, model._meta.object_name.lower()) |
|---|
| 412 | if template_name_field: |
|---|
| 413 | template_name_list = [getattr(obj, template_name_field), template_name] |
|---|
| 414 | t = template_loader.select_template(template_name_list) |
|---|
| 415 | else: |
|---|
| 416 | t = template_loader.get_template(template_name) |
|---|
| 417 | c = RequestContext(request, { |
|---|
| 418 | template_object_name: obj, |
|---|
| 419 | }, context_processors) |
|---|
| 420 | for key, value in extra_context.items(): |
|---|
| 421 | if callable(value): |
|---|
| 422 | c[key] = value() |
|---|
| 423 | else: |
|---|
| 424 | c[key] = value |
|---|
| 425 | response = HttpResponse(t.render(c), mimetype=mimetype) |
|---|
| 426 | populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name)) |
|---|
| 427 | return response |
|---|
| 428 | ''' |
|---|