Model engine
The model engine is the core of Evlet. It reads your model classes and uses them for the database, the forms, the checks and the API. This guide walks through it one idea at a time.
#How a save works
When someone saves a record, in the browser, over HTTP or from your Python code, Evlet runs the same steps in one database transaction:
- Permissions. May this person change this model, this record and these fields?
- Cleaning. Each value is checked against its field: its type,
required, limits and length. - Derived values.
derive()fills the values the record builds for itself. - Calculations. Formulas such as line amounts and totals are worked out.
- Validation. Your
validate()method checks rules across fields. - Storage. The record and its rows are written. If any step fails, nothing is written.
The browser runs the same calculations as a preview while people type. The server always has the last word.
#The guide
| Page | What you will learn |
|---|---|
| Models and fields | Write a model and choose its fields. |
| Links and children | Point to other records, and give a record its own table of rows. |
| Calculations and derive() | Totals, formulas and values a record builds for itself. |
| Validation | Field checks, cross-field rules and conditional fields. |
| Permissions and rules | Roles, field access and row scopes. |
| Actions and moves | States, moves, locks and buttons with inputs. |
| Documents and lifecycle | Confirm, cancel and reopen, with revisions. |
| Migrations | Change models safely: CreateModel, AlterField and frozen models. |
#The example app
Most samples come from one small app called shop. It has customers, products, invoices with lines, timesheets and receipts. Each model lives in its own file under apps/shop/models/. To follow along, create the app in your project with evlet app shop.
To run Python against a site from a script, the samples use a business context. It applies the same permission checks as the browser:
with app.business.context(user) as context:
customer = context.create(Customer, customer_name='Acme Trading', email='ops@example.com')
context.update(Customer, customer['id'], credit_days=45)context.create, update, get, list, move and action all check the user's permissions. They share one transaction, which commits when the with block ends.