12

In pydantic is there a cleaner way to exclude multiple fields from the model, something like:


class User(UserBase):
    class Config:        
        exclude = ['user_id', 'some_other_field']

I am aware that following works, but I was looking for something cleaner like django.


class User(UserBase):

    class Config:       
        fields = {'user_id': {'exclude':True}, 
                   'some_other_field': {'exclude':True}
                 }
muon
  • 12,821
  • 11
  • 69
  • 88

4 Answers4

8

Pydantic will exclude the class variables which begin with an underscore. so if it fits your use case, you can rename your attribues.

class User(UserBase):
    _user_id=str
    some_other_field=str
    ....
Dharman
  • 30,962
  • 25
  • 85
  • 135
N.Moudgil
  • 709
  • 5
  • 11
  • one possible issue is that strict type validation doesn't work for class variables with an underscore. you can pass a non-string to `_user_id` and it can cause the code to break somewhere you don't expect – Derek O Mar 17 '22 at 06:57
6

I wrote something like this for my json :

from pydantic import BaseModel


class CustomBase(BaseModel):
    def json(self, **kwargs):
        include = getattr(self.Config, "include", set())
        if len(include) == 0:
            include = None
        exclude = getattr(self.Config, "exclude", set())
        if len(exclude) == 0:
            exclude = None
        return super().json(include=include, exclude=exclude, **kwargs)

    

class User(CustomBase):
    name :str = ...
    family :str = ...

    class Config:
        exclude = {"family"}


u = User(**{"name":"milad","family":"vayani"})

print(u.json())

you can overriding dict and other method like.

milad_vayani
  • 398
  • 1
  • 4
  • 14
4

To exclude a field you can also use exclude in Field:

from pydantic import BaseModel, Field

class Mdl(BaseModel):
    val: str = Field(
        exclude=True,
        title="val"
    )

however, the advantage of adding excluded parameters in the Config class seems to be that you can get the list of excluded parameters with

print(Mdl.Config.exclude)
Galuoises
  • 2,630
  • 24
  • 30
2

A possible solution is creating a new class based in the baseclass using create_model:

from pydantic import BaseModel, create_model

def exclude_id(baseclass, to_exclude: list):
    # Here we just extract the fields and validators from the baseclass
    fields = baseclass.__fields__
    validators = {'__validators__': baseclass.__validators__}
    new_fields = {key: (item.type_, ... if item.required else None)
                  for key, item in fields.items() if key not in to_exclude}
    return create_model(f'{baseclass.__name__}Excluded', **new_fields, __validators__=validators)


class User(BaseModel):
    ID: str
    some_other: str

list_to_exclude = ['ID']
UserExcluded = exclude_id(User, list_to_exclude)

UserExcluded(some_other='hola')

Which will return:

> UserExcluded(some_other='hola')

Which is a copy of the baseclass but with no parameter 'ID'.

If you have the id in the validators you may want also to exclude those validators.

Ziur Olpa
  • 1,839
  • 1
  • 12
  • 27
  • You need to add __config__=baseclass.__config__ that include Config in new model. For example, it is very important when you use orm_mode=True etc – Roman Gerasimov Aug 07 '22 at 17:12