Repository: encode/django-rest-framework

Issue:
Should ignore any invalidly formed query parameters for OrderingFilter.
## Checklist

- [x] I have verified that that issue exists against the `master` branch of Django REST framework.
- [x] I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
- [x] This is not a usage question. (Those should be directed to the [discussion group](https://groups.google.com/forum/#!forum/django-rest-framework) instead.)
- [x] This cannot be dealt with as a third party library. (We prefer new functionality to be [in the form of third party libraries](http://www.django-rest-framework.org/topics/third-party-resources/#about-third-party-packages) where possible.)
- [x] I have reduced the issue to the simplest possible case.
- [ ] I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)

## Steps to reproduce

- Create a ViewSet with an OrderingFilter and add a field to order on (field_name)
- Call the viewset with `?ordering=--field_name`

## Expected behavior
No ordering to be applied

## Actual behavior
Throws a 500 error because --field_name is passed to the queryset because over [here](https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/filters.py#L268) an lstrip is done instead of just removing the first - character before validation.




Discussion:
Any chance you could include the error traceback - it's not obvious to me on first sight what the issue is here.
@tomchristie the thing is the value minus lstrip('-') is matched against existing fields but it passed as it is to the queryset. Result being that:

- "--field_name".lstrip('-') -> field_name which is valid
- .order_by('--field_name') is not valid

Hey folks,

Wanted to contribute to the test cases. 
Wanted to know if the expected behaviour mentioned in @hvdklauw above is correct. 

And by that logic can we add an arbitrary number of hyphens?
@vimarshc iirc, the current logic is to discard invalid ordering fields. To keep consistent I believe that "--field_name" should be simply discarded.

Resolving patch:
diff --git a/rest_framework/filters.py b/rest_framework/filters.py
--- a/rest_framework/filters.py
+++ b/rest_framework/filters.py
@@ -11,6 +11,7 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.db import models
 from django.db.models.constants import LOOKUP_SEP
+from django.db.models.sql.constants import ORDER_PATTERN
 from django.template import loader
 from django.utils import six
 from django.utils.encoding import force_text
@@ -268,7 +269,7 @@ def get_valid_fields(self, queryset, view, context={}):
 
     def remove_invalid_fields(self, queryset, fields, view, request):
         valid_fields = [item[0] for item in self.get_valid_fields(queryset, view, {'request': request})]
-        return [term for term in fields if term.lstrip('-') in valid_fields]
+        return [term for term in fields if term.lstrip('-') in valid_fields and ORDER_PATTERN.match(term)]
 
     def filter_queryset(self, request, queryset, view):
         ordering = self.get_ordering(request, queryset, view)


Test patch:
diff --git a/tests/test_filters.py b/tests/test_filters.py
--- a/tests/test_filters.py
+++ b/tests/test_filters.py
@@ -764,6 +764,23 @@ class OrderingListView(generics.ListAPIView):
             {'id': 1, 'title': 'zyx', 'text': 'abc'},
         ]
 
+    def test_incorrecturl_extrahyphens_ordering(self):
+        class OrderingListView(generics.ListAPIView):
+            queryset = OrderingFilterModel.objects.all()
+            serializer_class = OrderingFilterSerializer
+            filter_backends = (filters.OrderingFilter,)
+            ordering = ('title',)
+            ordering_fields = ('text',)
+
+        view = OrderingListView.as_view()
+        request = factory.get('/', {'ordering': '--text'})
+        response = view(request)
+        assert response.data == [
+            {'id': 3, 'title': 'xwv', 'text': 'cde'},
+            {'id': 2, 'title': 'yxw', 'text': 'bcd'},
+            {'id': 1, 'title': 'zyx', 'text': 'abc'},
+        ]
+
     def test_incorrectfield_ordering(self):
         class OrderingListView(generics.ListAPIView):
             queryset = OrderingFilterModel.objects.all()
@@ -883,6 +900,7 @@ class OrderingListView(generics.ListAPIView):
             queryset = OrderingFilterModel.objects.all()
             filter_backends = (filters.OrderingFilter,)
             ordering = ('title',)
+
             # note: no ordering_fields and serializer_class specified
 
             def get_serializer_class(self):