Right now, we’re storing our data in a Python dictionary - let’s modify our app so that we save it to the database.

We want to create a new row in the Articles table if the user clicks ‘Save’. We’ll write to the Data Table from inside a Server Module.

Anvil’s Server Modules are a full server-side Python environment. Server Modules cannot be edited or seen by the user, so we can trust them to do what we tell them. This is why we’ll use a Server Module to write to the Data Table. (Read more about our security recommendations for CRUD apps.)

Open the App Browser and create a Server Module by clicking the the blue ‘+ Add Server Module’ button underneath ‘Server Code’. This will open up a code editor.

Adding a Server Module

Let’s now write a server function to add a new row to the Articles Data Table. We’ll use the add_row method to do this.

Add this function to your Server Module:

@anvil.server.callable
def add_article(article_dict):
  app_tables.articles.add_row(
    created=datetime.now(),
    **article_dict
  )

The @anvil.server.callable decorator allows us to call this function from a client-side Form.

For more information on the difference between client and server code, read this explanation

We’re using the datetime library to set the ‘created’ column to the current date and time, so you’ll also need to import the datetime class at the top of your Server Module:

from datetime import datetime

The final step is to call this method from the Homepage Form when the user chooses to save a news article.

We want to call our add_article server function when the ‘Add an Article’ button is clicked and pass in the user inputs. We made our add_article server function available to our client Forms by decorating it as @anvil.server.callable.

This means we can call it from our client-side code using anvil.server.call('add_article', <arguments>)

Let’s call our add_article server function from our add_article_button_click function:

  def add_article_button_click(self, **event_args):
    # Initialise an empty dictionary to store the user inputs
    new_article = {}
    # Open an alert displaying the 'ArticleEdit' Form
    save_clicked = alert(
      content=ArticleEdit(item=new_article),
      title="Add Article",
      large=True,
      buttons=[("Save", True), ("Cancel", False)],
    )
    # If the alert returned 'True', the save button was clicked.
    if save_clicked:
      anvil.server.call('add_article', new_article)

If the user clicks ‘Cancel’, save_clicked will be False, so the data in our new_article dictionary will be discarded.

Run your app again, click the ‘Add an Article’ button, fill in the inputs, and click Save. Now, if you go to the Articles table in your Data Table, you’ll see the article in the Data Table.

Filling in the ArticleEdit form and checking that the data I entered is in the Data Table.