Skip to content

Commit ea630bf

Browse files
committed
Merge branch 'master' into filters
2 parents 5db900c + 8264222 commit ea630bf

File tree

10 files changed

+85
-13
lines changed

10 files changed

+85
-13
lines changed

docs/api-guide/filtering.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ The search behavior may be restricted by prepending various characters to the `s
260260
* '^' Starts-with search.
261261
* '=' Exact matches.
262262
* '@' Full-text search. (Currently only supported Django's MySQL backend.)
263+
* '$' Regex search.
263264

264265
For example:
265266

docs/api-guide/pagination.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The pagination API can support either:
1515

1616
The built-in styles currently all use links included as part of the content of the response. This style is more accessible when using the browsable API.
1717

18-
Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular `APIView`, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the `mixins.ListMixin` and `generics.GenericAPIView` classes for an example.
18+
Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular `APIView`, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the `mixins.ListModelMixin` and `generics.GenericAPIView` classes for an example.
1919

2020
## Setting the pagination style
2121

docs/topics/release-notes.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ You can determine your currently installed version using `pip freeze`:
4040

4141
## 3.2.x series
4242

43+
### 3.2.3
44+
45+
**Date**: [24th August 2015][3.2.3-milestone].
46+
47+
* Added `html_cutoff` and `html_cutoff_text` for limiting select dropdowns. ([#3313][gh3313])
48+
* Added regex style to `SearchFilter`. ([#3316][gh3316])
49+
* Resolve issues with setting blank HTML fields. ([#3318][gh3318]) ([#3321][gh3321])
50+
* Correctly display existing 'select multiple' values in browsable API forms. ([#3290][gh3290])
51+
* Resolve duplicated validation message for `IPAddressField`. ([#3249[gh3249]) ([#3250][gh3250])
52+
* Fix to ensure admin renderer continues to work when pagination is disabled. ([#3275][gh3275])
53+
* Resolve error with `LimitOffsetPagination` when count=0, offset=0. ([#3303][gh3303])
54+
4355
### 3.2.2
4456

4557
**Date**: [13th August 2015][3.2.2-milestone].
@@ -285,7 +297,8 @@ For older release notes, [please see the version 2.x documentation][old-release-
285297
[3.1.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.3+Release%22
286298
[3.2.0-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.0+Release%22
287299
[3.2.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.1+Release%22
288-
[3.2.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.1+Release%22
300+
[3.2.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.2+Release%22
301+
[3.2.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.2.3+Release%22
289302

290303
<!-- 3.0.1 -->
291304
[gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013
@@ -486,4 +499,20 @@ For older release notes, [please see the version 2.x documentation][old-release-
486499
[gh2776]: https://github.com/tomchristie/django-rest-framework/issues/2776
487500
[gh3261]: https://github.com/tomchristie/django-rest-framework/issues/3261
488501
[gh3260]: https://github.com/tomchristie/django-rest-framework/issues/3260
489-
[gh3241]: https://github.com/tomchristie/django-rest-framework/issues/3241
502+
[gh3241]: https://github.com/tomchristie/django-rest-framework/issues/3241
503+
504+
<!-- 3.2.3 -->
505+
[gh3249]: https://github.com/tomchristie/django-rest-framework/issues/3249
506+
[gh3250]: https://github.com/tomchristie/django-rest-framework/issues/3250
507+
[gh3275]: https://github.com/tomchristie/django-rest-framework/issues/3275
508+
[gh3288]: https://github.com/tomchristie/django-rest-framework/issues/3288
509+
[gh3290]: https://github.com/tomchristie/django-rest-framework/issues/3290
510+
[gh3303]: https://github.com/tomchristie/django-rest-framework/issues/3303
511+
[gh3313]: https://github.com/tomchristie/django-rest-framework/issues/3313
512+
[gh3316]: https://github.com/tomchristie/django-rest-framework/issues/3316
513+
[gh3318]: https://github.com/tomchristie/django-rest-framework/issues/3318
514+
[gh3321]: https://github.com/tomchristie/django-rest-framework/issues/3321
515+
516+
517+
518+

rest_framework/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"""
99

1010
__title__ = 'Django REST framework'
11-
__version__ = '3.2.2'
11+
__version__ = '3.2.3'
1212
__author__ = 'Tom Christie'
1313
__license__ = 'BSD 2-Clause'
1414
__copyright__ = 'Copyright 2011-2015 Tom Christie'

rest_framework/fields.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,10 @@ def get_value(self, dictionary):
385385
# If the field is blank, and null is a valid value then
386386
# determine if we should use null instead.
387387
return '' if getattr(self, 'allow_blank', False) else None
388-
elif ret == '' and self.default:
389-
return empty
388+
elif ret == '' and not self.required:
389+
# If the field is blank, and emptyness is valid then
390+
# determine if we should use emptyness instead.
391+
return '' if getattr(self, 'allow_blank', False) else empty
390392
return ret
391393
return dictionary.get(self.field_name, empty)
392394

rest_framework/filters.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,24 @@ def construct_search(self, field_name):
127127
return "%s__iexact" % field_name[1:]
128128
elif field_name.startswith('@'):
129129
return "%s__search" % field_name[1:]
130+
if field_name.startswith('$'):
131+
return "%s__iregex" % field_name[1:]
130132
else:
131133
return "%s__icontains" % field_name
132134

133135
def filter_queryset(self, request, queryset, view):
134136
search_fields = getattr(view, 'search_fields', None)
135137

136-
orm_lookups = [
137-
self.construct_search(six.text_type(search_field))
138-
for search_field in search_fields
139-
]
140138
search_terms = self.get_search_terms(request)
141139

142140
if not search_fields or not search_terms:
143141
return queryset
144142

143+
orm_lookups = [
144+
self.construct_search(six.text_type(search_field))
145+
for search_field in search_fields
146+
]
147+
145148
base = queryset
146149
for search_term in search_terms:
147150
queries = [

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# -*- coding: utf-8 -*-
33
import os
44
import re
5+
import shutil
56
import sys
67

78
from setuptools import setup
@@ -55,6 +56,9 @@ def get_package_data(package):
5556
print("You probably want to also tag the version now:")
5657
print(" git tag -a %s -m 'version %s'" % (version, version))
5758
print(" git push --tags")
59+
shutil.rmtree('dist')
60+
shutil.rmtree('build')
61+
shutil.rmtree('djangorestframework.egg-info')
5862
sys.exit()
5963

6064

tests/test_fields.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,30 @@ class TestSerializer(serializers.Serializer):
253253

254254

255255
class TestHTMLInput:
256-
def test_empty_html_charfield(self):
256+
def test_empty_html_charfield_with_default(self):
257257
class TestSerializer(serializers.Serializer):
258258
message = serializers.CharField(default='happy')
259259

260260
serializer = TestSerializer(data=QueryDict(''))
261261
assert serializer.is_valid()
262262
assert serializer.validated_data == {'message': 'happy'}
263263

264+
def test_empty_html_charfield_without_default(self):
265+
class TestSerializer(serializers.Serializer):
266+
message = serializers.CharField(allow_blank=True)
267+
268+
serializer = TestSerializer(data=QueryDict('message='))
269+
assert serializer.is_valid()
270+
assert serializer.validated_data == {'message': ''}
271+
272+
def test_empty_html_charfield_without_default_not_required(self):
273+
class TestSerializer(serializers.Serializer):
274+
message = serializers.CharField(allow_blank=True, required=False)
275+
276+
serializer = TestSerializer(data=QueryDict('message='))
277+
assert serializer.is_valid()
278+
assert serializer.validated_data == {'message': ''}
279+
264280
def test_empty_html_integerfield(self):
265281
class TestSerializer(serializers.Serializer):
266282
message = serializers.IntegerField(default=123)

tests/test_filters.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,23 @@ class SearchListView(generics.ListAPIView):
407407
]
408408
)
409409

410+
def test_regexp_search(self):
411+
class SearchListView(generics.ListAPIView):
412+
queryset = SearchFilterModel.objects.all()
413+
serializer_class = SearchFilterSerializer
414+
filter_backends = (filters.SearchFilter,)
415+
search_fields = ('$title', '$text')
416+
417+
view = SearchListView.as_view()
418+
request = factory.get('/', {'search': 'z{2} ^b'})
419+
response = view(request)
420+
self.assertEqual(
421+
response.data,
422+
[
423+
{'id': 2, 'title': 'zz', 'text': 'bcd'}
424+
]
425+
)
426+
410427
def test_search_with_nonstandard_search_param(self):
411428
with override_settings(REST_FRAMEWORK={'SEARCH_PARAM': 'query'}):
412429
reload_module(filters)

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ setenv =
1414
deps =
1515
django15: Django==1.5.6 # Should track minimum supported
1616
django16: Django==1.6.3 # Should track minimum supported
17-
django17: Django==1.7.8 # Should track maximum supported
18-
django18: Django==1.8.2 # Should track maximum supported
17+
django17: Django==1.7.10 # Should track maximum supported
18+
django18: Django==1.8.4 # Should track maximum supported
1919
djangomaster: https://github.com/django/django/archive/master.tar.gz
2020
-rrequirements/requirements-testing.txt
2121
-rrequirements/requirements-optionals.txt

0 commit comments

Comments
 (0)