Suppose I have a peewee model that looks more or less like this:
class MyModel(peewee.Model): a = peewee.IntegerField() b = peewee.IntegerField()
And I want to add a property to this model as follows:
@property def diff(self): return self.a - self.b
It is useful sometimes; now if Object is an instance of MyModel , I can easily check its diff for Object.diff .
What I cannot do is the following:
objects = list(MyModel.select().where(MyModel.diff < 17))
And this is because MyModel.diff is a simple property and probably always greater than 17. This is not Expression , like MyModel.a < 17 .
It would be nice to set diff as if it were a field; therefore, the user of this API will not need to know if a particular implementation a and b real fields and diff as virtual fields, or rather, a and diff as real fields and b as virtual.
Of course, my real intention is to use properties that in some cases include much more complex calculations presented on diff ; example:
@property def complicated_property(self): if 17 <= self.a <= 173: return a_complicated_math_function(self.a + self.b) return another_complicated_math_function(self.a * self.b ** 2)
On the other hand, it can be a very simple property, such as
@property def seven(self): return 7
This means that it cannot be converted to SQL at all, but must filter the results after they are received from the database.
Is it possible?
Update
I just opened the peewee playhouse hybrid methods / properties. They provide a partial solution to my question.
For example, my diff method could become hybrid_property and work as expected. My complicated_property cannot become one or at least looks like it; the if condition at the beginning will return either True or False continuously and will not act as a function.
Peewee probably has some more magic tricks; I will continue to search and report on my findings.