Skip to content

Commit

Permalink
Improve the fix for #2 by avoiding troublesome lookups in the template.
Browse files Browse the repository at this point in the history
  • Loading branch information
gnuworldman committed Jul 20, 2016
1 parent 94b207c commit 4134047
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 40 deletions.
26 changes: 1 addition & 25 deletions src/site_analytics/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,34 +64,10 @@ class Meta:
model = models.Request
fields = 'url', 'site', 'timestamp', 'username', 'ip_address', 'state'

def __getitem__(self, item):
"""Override to bypass errors in template lookup.
https://github.com/gnuworldman/site-analytics/issues/2
"""
if item == 'form':
try:
return super().__getitem__(item)
except exceptions.ValidationError:
raise KeyError(item)
return super().__getitem__(item)

def __len__(self):
"""Override to bypass errors in template lookup.
https://github.com/gnuworldman/site-analytics/issues/2
"""
try:
return super().__len__()
except exceptions.ValidationError:
return 0

@property
def qs(self):
"""Override to produce a REST Framework ValidationError."""
try:
return super().qs
except ValidationError as exc:
raise exceptions.ValidationError(exc.error_dict)
raise exceptions.ValidationError(exc.message_dict)
6 changes: 3 additions & 3 deletions src/site_analytics/templates/site_analytics/filter.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
{% block content %}
<link rel="stylesheet" href="{% static "admin/css/forms.css" %}" />
<form action="" method="get">
{{ filter.form.as_p }}
{{ form.as_p }}
<input type="submit" />
</form>
{% if filter|length %}
<br>
{% if show_data %}
<p>
<table>
<caption>Matching requests</caption>
<tr><th>URL<th>Timestamp<th>Other data
Expand Down
11 changes: 3 additions & 8 deletions src/site_analytics/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from rest_framework import status
from rest_framework.test import APITestCase

from site_analytics import filters, models
from site_analytics import models
from site_analytics._version import __version__


Expand Down Expand Up @@ -474,6 +474,8 @@ def test_filter_timestamp_invalid_format(self):
data = dict(timestamp_0='invalid datetime format')
response = self.client.get(self.path, data)
self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
self.assertDictEqual(dict(timestamp=['Enter a valid date/time.']),
response.data)

def test_filter_username_and_timestamp_not_after(self):
end = datetime.datetime(2001, 1, 1, tzinfo=UTC)
Expand All @@ -491,13 +493,6 @@ def test_filter_username_and_timestamp_not_after(self):

class FilterTestCase(APITestCase):

def test_getitem_override_passthrough(self):
"""Test that queryset indices still work with __getitem__ override."""
request = create_request(url='https://host.net/')
qs = models.Request.objects.filter(pk=request.pk)
filterset = filters.RequestFilter(queryset=qs)
self.assertEqual(request, filterset[0])

def test_get_page_no_input(self):
response = self.client.get('/filter.html')
self.assertEqual(status.HTTP_200_OK, response.status_code,
Expand Down
15 changes: 11 additions & 4 deletions src/site_analytics/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,16 @@ class FilterView(views.APIView):
template_name = 'site_analytics/filter.html'

def get(self, request, *args, **kwargs): # pragma: no cover
params = request.query_params
show_data = bool(request.query_params)
qs = models.Request.objects.all()
if not params:
qs = qs.none()
data = dict(filter=filters.RequestFilter(params, qs))
filter_ = filters.RequestFilter(request.query_params, qs)
if show_data:
show_data = filter_.form.is_valid()
# The form and show_data variables are passed in to work around errors
# related to validation, strictness, and template variable dot lookups.
# If the template used {{ filter.form }}, then it would attempt
# filter['form'] before filter.form, and filter.__getitem__('form')
# could raise an error if the form is invalid. Similarly, show_data
# is used instead of {{ filter|length }}.
data = dict(filter=filter_, form=filter_.form, show_data=show_data)
return response.Response(data)

0 comments on commit 4134047

Please sign in to comment.