Flask Blog: Models and Database

One major component of the blog involved the creation of several classes to model datasets for a database. For the database, these classes would be the models used to create the tables and relationships. Inside these classes, columns would be created by assignment attributes relevant characteristics, and methods could be used to verify if data in various ways.


Introduction:


After getting the basic application setup, the next component to include would be the model classes. These classes would stem from the flask extension flask-sqlalchemy. A few more configuration settings were created in config.py and the new extension added.


# config.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

application = Flask(__name__)
application.config["SECRET_KEY"] = "'0de3f3c030d7c2af36527463c9cf668a'"
# /// means it is a relative path from the current file: flask_blog.py --> site.db (in another folder somewhere)
application.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///static/database/site.db"
db = SQLAlchemy(application)


Next, an SQLite database called site.db was created with SQLAlchemy with the application object as the only argument. A python file called models.py was created to house the classes. Several imports would be required for the models.py, which included:


# models.py

from datetime import datetime
from flask_login import UserMixin
from config import db, login_manager


Database Models:


The first class that was created was the User class. This class would hold user information which included:


  • id
  • username
  • email
  • image
  • password
  • admin
  • One-to-many relationship to Posts
  • One-to-many relationship to Comments


The id would act as the primary key while the username, email, and image file would store the respective information. The username and email columns were designed to be unique to disallow duplicate entries. Passwords were designed to use a flask extension called flask_bcrypt to hash passwords. The admin column would allow access to parts of the site that would require admin permission, this was set to a Boolean value. There would be a one-to-many relationship to both the Post and Comment models.


# models.py

class User(db.Model, UserMixin):

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    image_file = db.Column(db.String(20), nullable=False, default="default.jpg")
    password = db.Column(db.String(60), nullable=False)
    # referencing the actual Post class, thats why it is uppercase P
    admin = db.Column(db.Boolean(),nullable=False,default=0)
    posts = db.relationship("Post", backref="author", lazy=True)
    comments = db.relationship("Comment", backref="user_comment", lazy=True)

    def __repr__(self):
        return f"User('{self.username}','{self.email}','{self.image_file}')"


The second class that was created was the Post class. This class housed information and relationships about blog posts, and included:


  • id
  • title
  • date posted
  • content
  • web map
  • summary
  • file uploads
  • user-id
  • One-to-many relationship to Comments


The id would act as the primary key, while the title and content would hold the title of the post and the article content. The date posted column would accept a date-time data type with the default being the date and time when the post was uploaded. The next few columns would require some processing of the uploaded data. The web map column was created to hold the HTML for web maps. The summary column would hold the summary of the post and was created using a small function.


def create_summary(content):
    summary_str = str()

    for index, char in enumerate(content):
        if index >= 300 and char == " ":
            return f"{summary_str}..."
        else:
            summary_str += char

    return f"{summary_str}..."


The file uploads column would hold the names of any files uploaded with the post. Finally, the user id column would act as a foreign key for the Post class. The Post model would have a one-to-many relationship with the Comments model.


# models.py

class Post(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    image_file = db.Column(db.String(20), nullable=False, default="default.jpg")
    content = db.Column(db.VARCHAR, nullable=False)
    webmap = db.Column(db.VARCHAR, nullable=True)
    summary = db.Column(db.VARCHAR, nullable=False)
    file_uploads = db.Column(db.VARCHAR,nullable=True)
    # can create a foreign key; referencing the id variable in the User class, so that is why it is lowercase u
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
    comments = db.relationship("Comment", backref="post_comment", lazy=True)

    def __repr__(self):
        return f"User('{self.title}','{self.date_posted}')"


The final class was the Comments model. The Comments model consisted of:


  • id
  • date posted
  • content
  • post id
  • user-id


The id would act as a primary key for the model. The date posted would be a date-time data type with the default being the time of the posting of the comment. The content column would hold the content of the comment. The Comment model would have two foreign keys, one for the post id and user id.


# models.py

class Comment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    content = db.Column(db.VARCHAR, nullable=False)
    post_id = db.Column(db.Integer, db.ForeignKey("post.id"), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)


Conclusion:


The models.py was is a major component of the application. In models.py, various classes were created which would act as the models for the database. Currently, three models exist, which include: User, Post, and Comments. The User model contains information about a user. The Post model contains information about a certain post. Finally, the Comments model contains information that pertains to a comment from a certain user on a specific post. The models are designed to provide structure for the database which is used in turn to house the data mentioned above.


Resources:



Comments: