Skip to content

Commit d1fe3f6

Browse files
committed
Merge pull request #2446 from tomchristie/django-18-alpha
Support 1.8-alpha.
2 parents e56f0a9 + 04a5f7b commit d1fe3f6

10 files changed

+38
-84
lines changed

.travis.yml

-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ env:
3333
matrix:
3434
fast_finish: true
3535
allow_failures:
36-
- env: TOX_ENV=py34-django18alpha
37-
- env: TOX_ENV=py33-django18alpha
38-
- env: TOX_ENV=py32-django18alpha
39-
- env: TOX_ENV=py27-django18alpha
4036
- env: TOX_ENV=py34-djangomaster
4137
- env: TOX_ENV=py33-djangomaster
4238
- env: TOX_ENV=py32-djangomaster

env/pip-selfcheck.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"last_check":"2015-01-23T11:37:11Z","pypi_version":"6.0.6"}

rest_framework/parsers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def get_filename(self, stream, media_type, parser_context):
298298
if 'filename*' in filename_parm:
299299
return self.get_encoded_filename(filename_parm)
300300
return force_text(filename_parm['filename'])
301-
except (AttributeError, KeyError):
301+
except (AttributeError, KeyError, ValueError):
302302
pass
303303

304304
def get_encoded_filename(self, filename_parm):

rest_framework/response.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,13 @@ def status_text(self):
8181

8282
def __getstate__(self):
8383
"""
84-
Remove attributes from the response that shouldn't be cached
84+
Remove attributes from the response that shouldn't be cached.
8585
"""
8686
state = super(Response, self).__getstate__()
87-
for key in ('accepted_renderer', 'renderer_context', 'data'):
87+
for key in (
88+
'accepted_renderer', 'renderer_context', 'resolver_match',
89+
'client', 'request', 'wsgi_request', '_closable_objects'
90+
):
8891
if key in state:
8992
del state[key]
9093
return state

rest_framework/utils/model_meta.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,28 @@ def _get_reverse_relationships(opts):
121121
"""
122122
Returns an `OrderedDict` of field names to `RelationInfo`.
123123
"""
124+
# Note that we have a hack here to handle internal API differences for
125+
# this internal API across Django 1.7 -> Django 1.8.
126+
# See: https://code.djangoproject.com/ticket/24208
127+
124128
reverse_relations = OrderedDict()
125129
for relation in opts.get_all_related_objects():
126130
accessor_name = relation.get_accessor_name()
131+
related = getattr(relation, 'related_model', relation.model)
127132
reverse_relations[accessor_name] = RelationInfo(
128133
model_field=None,
129-
related=relation.model,
134+
related=related,
130135
to_many=relation.field.rel.multiple,
131136
has_through_model=False
132137
)
133138

134139
# Deal with reverse many-to-many relationships.
135140
for relation in opts.get_all_related_many_to_many_objects():
136141
accessor_name = relation.get_accessor_name()
142+
related = getattr(relation, 'related_model', relation.model)
137143
reverse_relations[accessor_name] = RelationInfo(
138144
model_field=None,
139-
related=relation.model,
145+
related=related,
140146
to_many=True,
141147
has_through_model=(
142148
(getattr(relation.field.rel, 'through', None) is not None)

tests/test_filters.py

+1
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ def setUp(self):
467467
for d in data:
468468
DjangoFilterOrderingModel.objects.create(**d)
469469

470+
@unittest.skipUnless(django_filters, 'django-filter not installed')
470471
def test_default_ordering(self):
471472
class DjangoFilterOrderingView(generics.ListAPIView):
472473
serializer_class = DjangoFilterOrderingSerializer

tests/test_htmlrenderer.py

+6
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@ def get_template(template_name, dirs=None):
5656
return Template("example: {{ object }}")
5757
raise TemplateDoesNotExist(template_name)
5858

59+
def select_template(template_name_list, dirs=None, using=None):
60+
if template_name_list == ['example.html']:
61+
return Template("example: {{ object }}")
62+
raise TemplateDoesNotExist(template_name_list[0])
63+
5964
django.template.loader.get_template = get_template
65+
django.template.loader.select_template = select_template
6066

6167
def tearDown(self):
6268
"""

tests/test_parsers.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ def test_get_encoded_filename(self):
161161

162162
self.__replace_content_disposition('inline; filename=fallback.txt; filename*=utf-8--ÀĥƦ.txt')
163163
filename = parser.get_filename(self.stream, None, self.parser_context)
164-
self.assertEqual(filename, 'fallback.txt')
164+
# Malformed. Either None or 'fallback.txt' will be acceptable.
165+
# See also https://code.djangoproject.com/ticket/24209
166+
self.assertIn(filename, ('fallback.txt', None))
165167

166168
def __replace_content_disposition(self, disposition):
167169
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = disposition

tests/test_renderers.py

+12-73
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from collections import MutableMapping
2323
import datetime
2424
import json
25-
import pickle
2625
import re
2726

2827

@@ -618,84 +617,24 @@ class CacheRenderTest(TestCase):
618617

619618
urls = 'tests.test_renderers'
620619

621-
cache_key = 'just_a_cache_key'
622-
623-
@classmethod
624-
def _get_pickling_errors(cls, obj, seen=None):
625-
""" Return any errors that would be raised if `obj' is pickled
626-
Courtesy of koffie @ http://stackoverflow.com/a/7218986/109897
627-
"""
628-
if seen is None:
629-
seen = []
630-
try:
631-
state = obj.__getstate__()
632-
except AttributeError:
633-
return
634-
if state is None:
635-
return
636-
if isinstance(state, tuple):
637-
if not isinstance(state[0], dict):
638-
state = state[1]
639-
else:
640-
state = state[0].update(state[1])
641-
result = {}
642-
for i in state:
643-
try:
644-
pickle.dumps(state[i], protocol=2)
645-
except pickle.PicklingError:
646-
if not state[i] in seen:
647-
seen.append(state[i])
648-
result[i] = cls._get_pickling_errors(state[i], seen)
649-
return result
650-
651-
def http_resp(self, http_method, url):
652-
"""
653-
Simple wrapper for Client http requests
654-
Removes the `client' and `request' attributes from as they are
655-
added by django.test.client.Client and not part of caching
656-
responses outside of tests.
657-
"""
658-
method = getattr(self.client, http_method)
659-
resp = method(url)
660-
resp._closable_objects = []
661-
del resp.client, resp.request
662-
try:
663-
del resp.wsgi_request
664-
except AttributeError:
665-
pass
666-
return resp
667-
668-
def test_obj_pickling(self):
669-
"""
670-
Test that responses are properly pickled
671-
"""
672-
resp = self.http_resp('get', '/cache')
673-
674-
# Make sure that no pickling errors occurred
675-
self.assertEqual(self._get_pickling_errors(resp), {})
676-
677-
# Unfortunately LocMem backend doesn't raise PickleErrors but returns
678-
# None instead.
679-
cache.set(self.cache_key, resp)
680-
self.assertTrue(cache.get(self.cache_key) is not None)
681-
682620
def test_head_caching(self):
683621
"""
684622
Test caching of HEAD requests
685623
"""
686-
resp = self.http_resp('head', '/cache')
687-
cache.set(self.cache_key, resp)
688-
689-
cached_resp = cache.get(self.cache_key)
690-
self.assertIsInstance(cached_resp, Response)
624+
response = self.client.head('/cache')
625+
cache.set('key', response)
626+
cached_response = cache.get('key')
627+
assert isinstance(cached_response, Response)
628+
assert cached_response.content == response.content
629+
assert cached_response.status_code == response.status_code
691630

692631
def test_get_caching(self):
693632
"""
694633
Test caching of GET requests
695634
"""
696-
resp = self.http_resp('get', '/cache')
697-
cache.set(self.cache_key, resp)
698-
699-
cached_resp = cache.get(self.cache_key)
700-
self.assertIsInstance(cached_resp, Response)
701-
self.assertEqual(cached_resp.content, resp.content)
635+
response = self.client.get('/cache')
636+
cache.set('key', response)
637+
cached_response = cache.get('key')
638+
assert isinstance(cached_response, Response)
639+
assert cached_response.content == response.content
640+
assert cached_response.status_code == response.status_code

tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ deps =
2222
{py26,py27}-django{14,15}: django-oauth2-provider==0.2.3
2323
{py26,py27}-django16: django-oauth2-provider==0.2.4
2424
pytest-django==2.8.0
25-
django-filter==0.7
25+
{py26,py27,py32,py33,py34}-django{14,15,16,17}: django-filter==0.7
2626
defusedxml==0.3
2727
markdown>=2.1.0
2828
PyYAML>=3.10

0 commit comments

Comments
 (0)