|
| 1 | +title: django.http HttpResponseNotModified Python Code Examples |
| 2 | +category: page |
| 3 | +slug: django-http-httpresponsenotmodified-examples |
| 4 | +sortorder: 50063 |
| 5 | +toc: False |
| 6 | +sidebartitle: django.http HttpResponseNotModified |
| 7 | +meta: Example Python code for using the HttpResponseNotModified object provided by Django in the django.http module. |
| 8 | + |
| 9 | + |
| 10 | +[HttpResponseNotModified](https://docs.djangoproject.com/en/stable/ref/request-response/#django.http.HttpResponseNotModified) |
| 11 | +([source code](https://github.com/django/django/blob/master/django/http/response.py)) |
| 12 | +returns the |
| 13 | +[HTTP 304 status code](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) |
| 14 | +from a [Django](/django.html) web application view. The HTTP 304 status code |
| 15 | +indicates that the resource has not been modified since the client last requested |
| 16 | +it. |
| 17 | + |
| 18 | +[HttpResponseRedirect](/django-http-httpresponseredirect-examples.html) |
| 19 | +and |
| 20 | +[HttpResponsePermanentRedirect](/django-http-httpresponsepermanentredirect-examples.html) |
| 21 | +are other types of 300-level HTTP status codes that can be |
| 22 | +sent as a response by your Django application. |
| 23 | + |
| 24 | + |
| 25 | +## Example 1 from wagtail |
| 26 | +[wagtail](https://github.com/wagtail/wagtail) |
| 27 | +([project website](https://wagtail.io/)) is a fantastic |
| 28 | +[Django](/django.html)-based CMS with code that is open source |
| 29 | +under the |
| 30 | +[BSD 3-Clause "New" or "Revised" License](https://github.com/wagtail/wagtail/blob/master/LICENSE). |
| 31 | + |
| 32 | +[**wagtail / wagtail / utils / sendfile_streaming_backend.py**](https://github.com/wagtail/wagtail/blob/master/wagtail/utils/sendfile_streaming_backend.py) |
| 33 | + |
| 34 | +```python |
| 35 | +# Sendfile "streaming" backend |
| 36 | +# This is based on sendfiles builtin "simple" backend but uses a StreamingHttpResponse |
| 37 | + |
| 38 | +import os |
| 39 | +import re |
| 40 | +import stat |
| 41 | +from email.utils import mktime_tz, parsedate_tz |
| 42 | +from wsgiref.util import FileWrapper |
| 43 | + |
| 44 | +~~from django.http import HttpResponseNotModified, StreamingHttpResponse |
| 45 | +from django.utils.http import http_date |
| 46 | + |
| 47 | + |
| 48 | +def sendfile(request, filename, **kwargs): |
| 49 | + # Respect the If-Modified-Since header. |
| 50 | + statobj = os.stat(filename) |
| 51 | + |
| 52 | + if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'), |
| 53 | + statobj[stat.ST_MTIME], statobj[stat.ST_SIZE]): |
| 54 | +~~ return HttpResponseNotModified() |
| 55 | + |
| 56 | + response = StreamingHttpResponse(FileWrapper(open(filename, 'rb'))) |
| 57 | + |
| 58 | + response["Last-Modified"] = http_date(statobj[stat.ST_MTIME]) |
| 59 | + return response |
| 60 | + |
| 61 | + |
| 62 | +def was_modified_since(header=None, mtime=0, size=0): |
| 63 | + """ |
| 64 | + Was something modified since the user last downloaded it? |
| 65 | +
|
| 66 | + header |
| 67 | + This is the value of the If-Modified-Since header. If this is None, |
| 68 | + I'll just return True. |
| 69 | +
|
| 70 | + mtime |
| 71 | + This is the modification time of the item we're talking about. |
| 72 | +
|
| 73 | + size |
| 74 | + This is the size of the item we're talking about. |
| 75 | + """ |
| 76 | + try: |
| 77 | + if header is None: |
| 78 | + raise ValueError |
| 79 | + matches = re.match(r"^([^;]+)(; length=([0-9]+))?$", header, |
| 80 | + re.IGNORECASE) |
| 81 | + header_date = parsedate_tz(matches.group(1)) |
| 82 | + if header_date is None: |
| 83 | + raise ValueError |
| 84 | + header_mtime = mktime_tz(header_date) |
| 85 | + header_len = matches.group(3) |
| 86 | + if header_len and int(header_len) != size: |
| 87 | + raise ValueError |
| 88 | + if mtime > header_mtime: |
| 89 | + raise ValueError |
| 90 | + except (AttributeError, ValueError, OverflowError): |
| 91 | + return True |
| 92 | + return False |
| 93 | + |
| 94 | +``` |
| 95 | + |
0 commit comments