Killer Web Development

by Marco Laspe

8.2 Creating the message model

We will base our messages model on the model we created in section 3.1 - it had 3 fields:

  • an unique id
  • the content of the post and
  • an user_id of the user who wrote the post

Additionally we will add 2 more fields to our new message model:

  • the timestamp when the message was created
  • the timestamp when the message was last updated

Both new fields are time stamps, which means that they hold a certain date and time.

Wikipedia says

Timestamp

A timestamp is a sequence of characters or encoded information identifying when a certain event occurred, usually giving date and time of day, sometimes accurate to a small fraction of a second. The term derives from rubber stamps used in offices to stamp the current date, and sometimes time, in ink on paper documents, to record when the document was received.

!!! Image of the message model

User/Micropost associations

Again we need to associate the messages to an user. Every message will have one, and only one, user; but an user can have any number of messages.

!!! Image of the one user and several messages

In a more formal way we can use the following notation:

!!! Image of the message - user association

this is known as the Entity-Relationship-Model (a very basic one). If you have more complex data models it is much more accessible than our informal way.

Wikipedia says

Entity–relationship model

In software engineering, an Entity – Relationship model (ER model for short) is an abstract way to describe a database. It usually starts with a relational database, which stores data in tables. Some of the data in these tables point to data in other tables - for instance, your entry in the database could point to several entries for each of the phone numbers that are yours. The ER model would say that you are an entity, and each phone number is an entity, and the relationship between you and the phone numbers is 'has a phone number'. Diagrams created to design these entities and relationships are called entity–relationship diagrams or ER diagrams.

Now let's write the code for the model. Open models/db.py and at the end add

1.
db.define_table('message')

at the end. This defines a new table called message. Now we will add fields to the table; for that we use web2py's Field function. The Field function takes several arguments, the first is the name of the field, the second is the type of the field. Additional arguments can be used to imply certain restriction and behavior of the fields. We will use this later in the section. Add the field to you message table:

1.
2.
3.
4.
5.
6.
db.define_table('message',
Field('content', 'string'),
Field('user_id', db.auth_user),
Field('created', 'datetime'),
Field('updated', 'datetime')
)

This give us all the fields we need:

  • the id is created automatically by web2py
  • the content is a string
  • the user_id is a so called foreign key (reference) of the user model
  • the created is a datetime or timestamp
  • the updated is a datetime too

I think this is all pretty straight forward, except the user_id, this needs a bit of explanation. web2py makes it easy to make a reference from one database table to another:

Just create database field, containing the database name you want to reference to :

1.
Field('field_name', 'database_name')

Validating the fields for the message table

The fields in the message model have certain restrictions:

  1. Most important our messages must have of a minimum of 1 character and can be up to 280 characters long - that's twice as much as Twitter's.
  2. The user_id must have an entry in the auth_user table and it should be the current user.
  3. Every message must have a timestamp when it's created and when it's updated.

To enforce this behavior add the following lines of code to db.py:

1.
2.
3.
4.
5.
6.
7.
8.
9.
db.message.content.required = True
db.message.content.requires = IS_LENGTH(280, 1)

db.message.user_id.required = True
db.message.user_id.requires = IS_IN_DB(db, 'auth_user.id', '%(nickname)s')

db.message.created.required = True

db.message.updated.required = True

I think the code needs some explanation: the first line makes sure that the content field is required; the second uses what web2py calls a validator, it enforces that users can only insert messages with 1 to 280 characters. The fourth line uses another validator, it enforces, that the user can only insert id's from the auth_user table. The last parameter %(nickname)s tells web2py to show the nickname of the user in the entry form.

Let's see how the form looks like in the admin area of web2py, go to and play a bit with the form, insert different values, looks how the form behaves.

Default Values

This looks quite good so far, but we could use some reasonable default values for the user_id, created and updated field:

  1. user_id should have the default value of the logged in user - cause you can only send messages for yourself.
  2. created and updated should have the current time

web2py makes in very easy to put in these values, just add:

1.
2.
3.
db.message.user_id.default = db.auth_user
db.message.created.default = request.now
db.message.updated.default = request.now

to your db.py and your done. You can assign a default value to every database field with the following pattern db_name.table_name.user_id.default in our case we assign the current user with the db.auth_user expression as the default value to user_id; request.now gives you the current timestamp, we assign it to the default value of created and updated

Again go to http://localhost:8000/tukker/appadmin/insert/db/message and notice the difference. The User field is not set by default, because there is no user in the admin area.


Books often read by web2py and Python experts:

Comments

Leave a Reply

Required fields are marked *.