2

Is it correct, that in Web2Py you are not able to create custom methods within "models", so that they could contain business logic you want models to implement?

In case of Django you can just do something like:

class Aircraft(models.Model):
    '''I am an aircraft. I can fly, if I am created in Django.
    '''
    name = models.CharField(max_length=20)
    def fly(self):
        # ... some advanced logic here ...
        return 'I am flying'

But is it possible to do something like that (create custom methods) in Web2Py without the need to write the whole ORM system from the beginning or to share single method between instances of all the tables? Is there any established way to do that? For example:

db.define_table("aircrafts",
    Field("name", type="string", length=20)
)

aircraft = db(db.aircrafts).select().first()

# I am an aircraft too, please make me fly
aircraft.fly()
Tadeck
  • 132,510
  • 28
  • 152
  • 198

1 Answers1

2

Yes, you can define virtual fields:

db.aircrafts.fly = Field.Virtual(lambda row: 'I am flying')
aircraft = db(db.aircrafts).select().first() 
print aircraft.fly

or

db.aircrafts.fly = Field.Lazy(lambda row: 'I am flying')
aircraft = db(db.aircrafts).select().first() 
print aircraft.fly()

In the first example above, the "fly" value is automatically calculated for all records when they are selected. In the second example, the calculation is lazy and only executed when .fly() is actually called on a specific record.

You can also do this with old style virtual fields, which may be better for complex functions.

Note, this is handled differently from Django because web2py uses a database abstraction layer (DAL) rather than an ORM. Tables are not modeled as custom classes but as instances of the DAL Table class.

Anthony
  • 25,466
  • 3
  • 28
  • 57
  • Good, it is probably something that could help me implement part of what I wanted - it could significantly increase web2py's models' usability for me. But **is it possible to add custom methods that actually take more parameters than the row?** Are there any problems connected to such methods? The documentation you referenced says: "_Notice that each method of the class that takes a single argument (self) is a new virtual field._". Does it mean that if I try to implement method designed to be used like `aircraft.fly(speeds.FAST, dirs.NORTH)` (more arguments), I will hit the wall at some point? – Tadeck Mar 07 '12 at 19:55
  • Note, new style lazy virtual fields can take additional arguments when they are called. See the Field.Lazy example [here](http://web2py.com/books/default/chapter/29/6#New-style-virtual-fields-%28experimental%29). You may be able to specify additional arguments with old style lazy virtual fields as well, but I haven't tried it. – Anthony Mar 07 '12 at 21:27
  • Thank you for your input. I am now accepting your answer as the one answering my question. I have other question you could probably answer: [Can I include partial view in Web2Py, passing specific variables into it?](http://stackoverflow.com/questions/9674630/can-i-include-partial-view-in-web2py-passing-specific-variables-into-it). I did not find any help regarding this within the official documentation. – Tadeck Mar 12 '12 at 20:56