Suppose I have a peewee model which looks more or less as follows:
class MyModel(peewee.Model):
a = peewee.IntegerField()
b = peewee.IntegerField()
And I wish to add a property to that model as follows:
@property
def diff(self):
return self.a - self.b
This is helpful sometimes; now, if Object
is a MyModel
instance, I can easily check its diff
with Object.diff
.
What I can't do is the following:
objects = list(MyModel.select().where(MyModel.diff < 17))
And this is since MyModel.diff is a simple property, and is probably always greater than 17. It is not an Expression
like MyModel.a < 17
.
It would be very nice to expose diff
as if it was a field; so the user of that API will not need to know whether the specific implementation has a
and b
as real fields and diff
as a virtual one, or rather a
and diff
as real fields and b
as a virtual one.
Of course, my real intention is to use properties which involve, in some cases, much more sophisticated calculation that that presented on diff
; an example is
@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 it cannot, in general, be converted to SQL, but should rather filter the results after they are retrieved from the database.
Is that possible?
Update
I've just discovered peewee playhouse's hybrid methods/properties. These provide a partial solution to my question.
For example, my diff
method can become a hybrid_property
, and work as expected. My complicated_property
cannot become one, or at least it seems like it; the if
condition in its beginning will return either True
or False
constantly, and will not act as a function.
Peewee probably has some more magic hiding there; I'll keep looking and report my findings.