Chapter 4:
Add news articles to the database
So far, we’ve put together an add/edit form with inputs relating to news articles.

It’s time to connect it up to our database and save articles that the user enters. This is the ‘Create’ part of our CRUD app.
The process will look like this:
- The user clicks the ‘Add an article’ button
- A popup appears, displaying the content of the ‘ArticleEdit’ Form
- The user fills in the inputs
- The user clicks either ‘Save’ or ‘Cancel’
- If the user clicks save, store the article. Otherwise, discard the article.
We’ll walk through these steps below.
Step 1: Display an alert when the user clicks 'Add an Article'
We want to display our ‘ArticleEdit’ Form when a user clicks the ‘Add an article’ button.
We’ll use Events for this.
Click on ‘Homepage’ in the App Browser to go back to your UI. Click on your ‘Add an article’ Button, and scroll to the bottom of the Properties Panel. You’ll see a list of events for the Button.
Click the blue arrows next to ‘click’.

Configuring a click event handler from the Properties pane.
You will be taken to the Form Editor’s ‘Code’ view, where you’ll see an add_article_button_click
method on your Form that looks like this:
def add_article_button_click(self, **event_args):
"""This method is called when the button is clicked"""
pass
This is the Python method that runs when the ‘Add an article’ Button is clicked.
When someone clicks this button, we want to display a popup Form that users can fill out to save a new article. We do this using Alerts.
To display a simple alert, change your click handler to trigger an alert as follows:
def add_article_button_click(self, **event_args):
# Display a popup that says 'You clicked the button'
alert("You clicked the button")
To see it in action, click the ‘Run’ button at the top of the screen:

You’ll see your app running. Click the ‘Add an article’ button and your popup should appear!

Step 2: Put the ArticleEdit Form in the alert
We want our alert to display the ‘ArticleEdit’ Form. To do this, we first need to import the ArticleEdit Form inside our Homepage Form.
Add this line to the top of your ‘Homepage’ Form:
from ..ArticleEdit import ArticleEdit
We can now display the ‘ArticleEdit’ Form in our popup by customising the alert using Anvil’s custom popup styles. Set the content
property of the alert to an instance of the ‘ArticleEdit’ Form, set the title
property to “Add an article”, and set the large
property to True
:
def add_article_button_click(self, **event_args):
# Open an alert displaying the 'ArticleEdit' Form
alert(
content=ArticleEdit(),
title="Add Article",
large=True,
)
When you run your app and click the button, you should get the ArticleEdit form in a popup box:

Step 4: Store the data entered in the form
Let’s make the form store the title, content, image and category into our ‘Articles’ table when the user hits ‘Save’.
When the information is first entered, we’ll store it in a Python dictionary. Then if the user hits ‘Cancel’, we can just discard the dictionary - nothing is saved in the Data Table.
We’ll store this dictionary in the item
property of the ArticleEdit Form.
self.item
that can be accessed in the Form’s code. We’ll initialise our ArticleEdit Form with an empty dictionary as its self.item
.Edit your add_article_button_click
function to look like this:
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:
print(new_article)
It’s important to remember to change
ArticleEdit()
to ArticleEdit(item=new_article)
This means self.item
will start as an empty dictionary and we’ll update it as the user fills in the form.
We can update self.item
using Data Bindings. You can find Data Bindings in the Properties panel
for each component, near the top:

Select the ArticleEdit Form. For each of the ‘name’, ‘content’, and ‘category’ inputs, add a Data Binding to self.item
:
title_box
: Bind thetext
property toself.item['title']
content_box
: Bind thetext
property toself.item['content']
category_box
: Bind theselected_value
property toself.item['category']

For the FileLoader component, when the user uploads an image, we want to add it to self.item
. To do this, we set an event handler on the FileLoader component which will run when the user uploads an image.
Double click the FileLoader component to create a method for the change
event - the change
event is raised when a user uploads a file. Its file
argument is a Media object containing the chosen file:

Edit the image_uploader_change
method to look like this:
def image_uploader_change(self, file, **event_args):
"""This method is called when a new file is loaded into this FileLoader"""
# Add the image to self.item
self.item['image'] = file
Now run your app, click on ‘Add new article’, fill in all the fields, upload an image and click the ‘Save’ button.
You should now see your new_article
dictionary printed in the Output Panel

Step 5: Save the data to the 'Articles' table
We’ve got the data in a Python dictionary - now we want to 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.)
Create a Server Module by clicking the ‘+’ next to Server Code in the App Browser. You’ll see some code with a yellow background:

We’ll 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 client code.
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 client when the user chooses to save a news article.
We want to call our add_article
server function when the button is clicked, and pass in the user inputs. We made our add_article
server function available to our client-side code 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.

Great! We can now add news articles to our Data Table.
That’s the ‘C’ in our CRUD app, and the bulk of the work is out of the way - the Read, Update and Delete will be plain sailing now.
In Chapter 5, we’ll read the list of stored items and display it to the user. That’s the ‘R’ in our CRUD app.