Add BaseModel.iter() method which will behave exactly like a dict, but without converting nested values to dict by default and will be a generator instead
Imagine you want to iterate through values in model, but also need to exclude some, or use aliases instead of attributes. So what you need to do is write something like this:
for attr, value in model.dict(exclude={...}, by_alias=True).items():
do_something(attr, value)
Obviously, in this case python will firet evaluate model.dict(exclude={...}, by_alias=True). part, going through all values and only then you will be able to iterate, going through the same values again.
Also, by using dict nested values are force-converted to dict, and this might be very slow when we just want to iterate through top-level values.
We also cannot use existing _iter(), because some work is actually done in dict()
By having iter() method we can bypass this double-iteration problem and converting-to-dict problems:
for attr, value in model.iter(exclude={...}, by_alias=True):
do_something(attr, value)
This already exists!
It's called ._iter().
Should be documented I guess.
This already exists!
It's called ._iter().
Yeah, but I mentioned, why it cannot be used in this case:
We also cannot use existing _iter(), because some work is actually done in dict()
By some work i mean resolving aliases keys and excluding the values
I don't want to add more public method to models, best I think to implement this yourself.
If there's a simple way to achieve this with changes to existing functions of happy review a PR.
Sorry, I missed your comment when replying in a hurry.
I don't want to add more public method to models, best I think to implement this yourself.
Just to be clear, thats valid even if ._iter() itself would become public without adding any new methods?
If there's a simple way to achieve this with changes to existing functions of happy review a PR.
I guess the simplest way would be to move those excluding and aliases stuff from .dict() to ._iter(), that will also simplify .dict() too.
I'll try to play with it soon and will be happy to make a PR once it'll be done.
For what it's worth, I would be in favor of moving logic from dict into _iter, assuming it didn't result in meaningful performance penalties in any public methods -- I think it would simplify/result in a smaller diff for the implementation of dump_as_type from #812, and the related serialization performance improvements (even when not dumping as a specified type).