17

Is there an efficient way to exclude fields from the function values() or values_list.

e.g

Videos.objects.filter(id=1).get().values()

I want to exclude from this queryset the field duration.

I know that I can specify fields what I want to have in the result but what if I want everything but only one field not. Like in the cases if I have 20 fields and if I want only one from them not.

Thanks

Azd325
  • 5,752
  • 5
  • 34
  • 57

2 Answers2

35

You must use defer This will not add defined fields to your select query.

Videos.objects.filter(...).defer('duration')
Pramod
  • 5,150
  • 3
  • 45
  • 46
Mp0int
  • 18,172
  • 15
  • 83
  • 114
  • 3
    Before using `defer()`, read the [note in the documentation](https://docs.djangoproject.com/en/stable/ref/models/querysets/#defer): it's intended for advanced use-cases. – natka_m Aug 18 '20 at 12:35
  • Note that the question was "how to exclude fields from values() or values_list()". Calling one of those two methods after calling `defer` will still contain the deferred field. Example : `MyObject.objects.defer("created_at").values().first()["created_at"]` returns `datetime.datetime(...)` when you would expect a `KeyError` – Sunder May 03 '23 at 09:50
20

You can get all fields first, then pop out the fields you do not want:

fields = Video._meta.get_all_field_names()
fields.remove('id')
Video.object.filter(...).values(*fields)
iMom0
  • 12,493
  • 3
  • 49
  • 61
  • 3
    To get the field names directly you can use: ``Video._meta.get_all_field_names()`` – codeape May 31 '13 at 10:09
  • 7
    The `get_all_field_names()` method was deprecated some time ago and removed. Now you have to do: `[f.name for f in Video._meta.get_fields()]`, see this answer: https://stackoverflow.com/a/3106314/4744341 – natka_m Aug 18 '20 at 12:48