Introduction

In this part 4 of a multi-piece series for building a messaging system, we set up the ability for the user to make a forum post with Python and Postgres as the primary tools. We’ll utilize the Django and Psycopg2 frameworks for request, render, and other database-related functions. In this tutorial document, the main database-related function we use is to execute an “INSERT INTO” SQL command to add a post to our database.

Prerequisites

See parts 1 through 3, where we developed the underlying Postgres tables, a registration form, and the SQL and Python application needed for user registration: Use Django for Forum Registration with Python and Postgres: https://oceanmedia.net/use-django-for-a-forum-part-1-registration

Django forum messages lesson overview

We will start out by building an HTML page that will have an HTML form in it that the user can use to type in a message they need to be posted. Next, we’ll build a Python application that uses Request and Render to send the user to the HTML page as well as get the user’s submitted data. Finally, we’ll insert their new message into tbl_posts.

 

Django HTML page 

Below is the HTML for a posting screen for our forum messaging system. Name this file “post.html”:

<form id='form_post' name='form_post' action='/replyPost?id_user={{id_user}}&id_parent={{id_message}}' method='post' onsubmit='return true;'>
<div class="frm-record">
<div class="frm-input-caption">Topic:</div>
<div class="frm-input-input"><input type="text"  name="t_subject_topic"></div>
</div>
<div class="frm-record">
   	<div class="frm-input-caption">Your message:</div>
   	<div class="frm-input-input"><textarea name="t_post"></textarea></div>
</div>
<div>
 	<input type="submit" class="frm-btn-save" name="btn_add_user_go" value='Register'>
</div>
</form>

The form above is displayed via Django’s render function and the data is getd via Django’s Request function.

Django Render

Django’s Render function sends an HTML page to the user’s view. Render can use dynamic content by sending parameters with the function. The server will incorporate the dynamic content into the page and send the resulting HTML on to the client browser. PHP and Classic ASP work in an almost identical manner.

Django Render Example

 

import Django
from django.shortcuts import render
return render("post.html", {t_post : "Text to send for the h1 tag"})

Analysis

– t_post: The text we placed in the “t_post” parameter is sent to post.html, the html page we developed above, that receives and displays t_post in the h1 tag. Note: rather than use “t_post”, you can call this variable anything and even include multiple parameters within the render Django function.

 

Django request from HTML

The “request” function is used to pull data that was submitted either by form “post” or by a querystring “get”. In this lesson we have used it to request from a form post. 

# In the program we're building, we're not using the querystring version of request but are showing it here for you to see how it works and so you can compare it to the version that gets form data.
value_gotten_from_querystring = request.get[field_name_from_retrieve]
# THIS is the version of request we have used for our forum system:
value_gotten_from_form_post = request.post[field_name_from_post, default value when empty)

 Analysis

– **field_name_from_get**: This is the name of the field submitted; how it was named in a querystring or where method = ‘get’ in the form. GET is added to the end of a URL.
– **field_name_from_post**: This is the field name submitted via the form where method = ‘post’ like you see in the form tag of the HTML above.
– **default value when empty**: If an empty or null value was submitted by the user for the field because they left the field empty, this is the value that will be received in the value_gotten_from_form_post piece we showed you in the syntax above.

Let’s take a examine how that works with an applicable example:

An example of how we might use Django’s Request function can be used in the “real world”, like for example, in creating a forum system or message board:

t_subject_topic = request.post["t_subject_topic", "")
t_post = request.post["t_post", "")

Analysis

– t_subject_topic: Gets the value the user entered into the HTML input tag called “t_subject_topic” and places that value in the Python variable we also named “t_subject_topic”.
– t_post: Gets the value the user entered into the HTML textarea tag called “t_post” and places that value in the Python variable we also named “t_post”.

Now for a brief examine inserting this data into Postgres:

 

Postgres Insert Row

s = ""
s += "INSERT INTO tbl_posts "
s += "("
s += " id_user"
s += ", t_subject_topic"
s += ", t_post"
s += ") VALUES ("
s += " (%id_user)"
s += ", '(%t_subject_topic)'"
s += ", '(%t_post)'"
s += ")"
db_cursor.execute(s, [id_user, t_subject_topic, t_post])

Because we care about security from hacking, we used a parameterized query for our SQL and used psycopg2’s cursor object and execute method.

Finally, let’s write the full Python source code for our messaging system.

 

Full Source Code in Python

import Django
from django.shortcuts import render
import psycopg2
import hashlib

app = Django(__name__)
@app.route("/showTopics", methods=["POST","GET"])

# Connection credentials for Postgres
t_host = "database host address"
t_port = "5432"
t_dbname = "database name"
t_user = "database user name"
t_pw = "password"
# Using Psycopg2 to create a connection object
db_conn = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
# Using Psycopg2 to create a cursor object
db_cursor = db_conn.cursor()

# Set up globals
id_user = 23 # Once you have incorporated registration from piece 1 of this series of lessons, you won't want to hard code the value for id_user.
id_message = 0

# NEW: This is the new function that handles a new post.
def replyPost():
    return render("post.html", {id_message:id_message, id_user:id_user, t_text_for_h1 : "Forum Post"})
    id_user = request.get['id_user']
    id_parent = request.get['id_parent']
    t_subject_topic = request.post['t_subject_topic']
    t_post = request.post['t_post']

    s = ""
    s += "INSERT INTO tbl_posts "
    s += "("
    s += " id_user"
    s += ", id_parent"
    s += ", t_subject_topic"
    s += ", t_post"
    s += ") VALUES ("
    s += " (%id_user)"
    s += ", (%id_parent)"
    s += ", '(%t_subject_topic)'"
    s += ", '(%t_post)'"
    s += ")"
    db_cursor.execute(s, [id_user, id_parent, t_subject_topic, t_post])
    db_cursor.close()

def showTopics():
    s = ""
    s += "SELECT"
    s += " id"
    s += ", t_subject_topic"
    s += ", d_changed"
    s += "FROM tbl_posts"
    s += "ORDER BY"
    s += " d_changed DESC"
    try:
        db_cursor.execute(s)
        # Create list of columns for the record returned:
        db_records = db_cursor.fetchall()
    except psycopg2.Error as e:
        t_msg = "SQL error: " + e + "/n SQL: " + s
        return render("error.html", {t_msg : t_msg})
    db_cursor.close()

    return render("topics.html", {db_records:db_records, id_user:id_user, t_text_for_h1:"Forum Message Topics"})
    id_user = request.get['id_user']
    id_message = request.get['id_message']

def showMessage():
    s = ""
    s += "SELECT"
    s += " t_post"
    s += "FROM tbl_posts"
    try:
        db_cursor.execute(s)
        # Create list of columns for the record returned:
        db_record = db_cursor.fetchone()
    except psycopg2.Error as e:
        t_msg = "SQL error: " + e + "/n SQL: " + s
        return render("error.html", {t_msg : t_msg})
    db_cursor.close()

    return render("message.html", db_record=db_record, t_text_for_h1 = "Forum Full Message Detail")

Conclusion

In this final part (4) of a four-part series of tutorials for creating a messaging application, we enabled the user to make a forum post with Python and Postgres as the primary tools. We utilized the Django and Psycopg2 frameworks for request, render, and some other database-related features. In this tutorial document, the main “new” database-related function we learned to use was the “INSERT INTO” SQL command, executed to add a post to our database as a new row.