Should Query.add_ordering() raise FieldError exception?

The add_ordering() method has a call to the names_to_path() function with the following comment:

# names_to_path() validates the lookup. A descriptive
# FieldError will be raise if it's not.
self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)

(version: 3.2; path: django.db.models.sql.query, ~1989 line)

Function names_to_path have fail_on_missing argument, but is don’t pass in call from add_ordering (== fail_on_missing=False).
It’s normal ?

It was added after the closed ticket #31426 (Add proper field validation to QuerySet.order_by.) – Django

(I previously duplicated this in the google django-users group mailing list)

Using order_by with an invalid field name does end up throwing a FieldError exception.
From a quick test in shell_plus:

>>> User.objects.order_by('fake_field')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/whitesellk/ve/p3.10-d4.0/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/whitesellk/ve/p3.10-d4.0/lib/python3.10/site-packages/django/db/models/query.py", line 1180, in order_by
    obj.query.add_ordering(*field_names)
  File "/home/whitesellk/ve/p3.10-d4.0/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1960, in add_ordering
    self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
  File "/home/whitesellk/ve/p3.10-d4.0/lib/python3.10/site-packages/django/db/models/sql/query.py", line 1522, in names_to_path
    raise FieldError("Cannot resolve keyword '%s' into field. "
django.core.exceptions.FieldError: Cannot resolve keyword 'fake_field' into field. Choices are: date_joined, email, first_name, groups, id, ... <snipped>

Notice that the exception is raised in names_to_path being called from add_ordering.

1 Like

Apparently I was in a hurry,
I tried to check of the relations when using order_by before make request to DB, but forgot that quearyset are lazy, and I got an error in sql compile time
Thank you for your reply!
But I still have to fix it for myself using the Monkey patching method.
Is there another way to check for wrong relations?

I’m not following what you’re trying to say here.

What exactly are you looking to do?

I pass parameters to some_queryset = some_queryset.order_by(*ordering),
which come raw from requests using OrderingFilter in DRF.
If the parameters are incorrect, I will get FieldError and the server give the response “error, code 500”.

How do I check that the passed parameters will not raise exception without making request to database?

Sorry, if my sentences difficult for understanding, english is not my native language

I’m curious here - the DRF OrderingFilter will filter out invalid fields. How are invalid fields getting into your query?

Also, you could look at rest_framework.filters.OrderingFilter.get_valid_fields to see how they validate the supplied field names.

Beyond that, Python’s philosophy in general tends to be “assume it’s going to work, and catch the exceptions.” You could wrap the queryset in a try, except block to catch a FieldError.

The request with GET query params is passed through all filter_backends specified in a ViewSet, including the OrderingFilter. For the ViewSet, the ordering_fields field is set to __all__. By-default, the filter ignore fields with nested relations (like user__groups).

But i overwritten OrderingFilter.remove_invalid_fields method for not skip fields with “__” notation and all fields append to order_by list, including probably invalid. OrderingFilter.get_valid_fields not check field names so deep like names_to_path method in Query class

FieldError raise only at making request to db. it will be too late. i will loss queryset and can’t answer to request, because it is last point, ‘all or nothing’ situation.

My suggestion:

You could then implement your own field name validation function, using the supplied function as a guide.

Or, you could subclass rest_framework.filters.OrderingFilter to supply your own get_valid_fields method, and use your subclass to perform the filtering.

Any Updates here? Facing the same issue while ordering the field.

I’ve already forgotten what I did in result. But it seems like I just allowed sorting by all fields in View class.
Can you tell a little more about your issue ?

If you’re having an issue for which you would like some assistance, please open up a new topic to discuss it. Include the full error message you are receiving (if any).

@KenWhitesell @k-talipov
I have added here all the details:

Do let me know if any further information is required.

1 Like