pythondjangodjango-modelsdjango-querysetdjango-managers

How to make Django values() exclude some fields?


I have multiple models which has fields like "created_at" "updated_at" which I don't want to get with objects.values().

Does Django has any way to exclude fields in values()?

I know people refer to defer(), but it doesn't return QuerySet<Dict> like values() instead returns QuerySet<Model>.

I tried objects.defer("created_at", "updated_at").values(), but it includes those 2 deferred fields in the resulting Dict.

I see defer().query only selecting the non-exluded fields in the SQL, but using defer(..).values() resets the deferred fields and selects all fields.

I cannot specify which field I want, since different model has different fields, I can only specity which fields I don't want. So I cannot use values('name', 'age', ...)

I'm planning to use a CustomeManager, which I can use in all model.

Example:

class CustomManager(models.Manager):
    def values_excluded(self):
        return self.values() # somehow exlude the fields and return QuerySet<Dict>

class ExampleModel(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    created_at = models.DateTimeField()
    updated_at = models.DateTimeField()
    objects = CustomManager()

ExampleModel.objects.values_excluded()

Is there any way in Django or do I have to manually delete those keys from the resulting Dict from values()?


Solution

  • This should work:

    class CustomManager(models.Manager):
    
        def values_excluded(self, *excluded_fields):
            included_fields = [f.name for f in self.model._meta.fields if f.name not in excluded_fields]
            return self.values(*included_fields)