<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Stefano Ferrari</title>
    <description>The latest articles on Forem by Stefano Ferrari (@rquattrogtl).</description>
    <link>https://forem.com/rquattrogtl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F383301%2F2881e1cd-7854-4b55-9b77-8828c4cf36d1.jpeg</url>
      <title>Forem: Stefano Ferrari</title>
      <link>https://forem.com/rquattrogtl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rquattrogtl"/>
    <language>en</language>
    <item>
      <title>Django, PostgreSQL, Docker and Jasper Reports.</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Thu, 10 Apr 2025 19:36:23 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/django-postgresql-docker-and-jasper-reports-167</link>
      <guid>https://forem.com/rquattrogtl/django-postgresql-docker-and-jasper-reports-167</guid>
      <description>&lt;p&gt;I was working on a small project aimed at simplifying the creation and tracking of various types of office documents. The project should include a database of all documents entered, along with their associated due dates. These documents pertain to both clients and suppliers, so the system needs to handle multiple aspects.&lt;/p&gt;

&lt;p&gt;My idea was to use Django as the backend framework and deploy the application using Docker. It was a fun experience overall. Initially, my project was structured like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;businesshub/
   |_ accounts
   |_ anagrafiche
   |_ businesshub
   |_ core
   |_ documents
   |_ templates
.env
.env.prod
docker-compose.yml
Dockerfile
entrypoint.sh
manage.py
requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My Dockerfile was as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use a base image with Python
FROM python:3.11-slim

# Environment variables to prevent bytecode generation and enable unbuffered output
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Set the working directory inside the container
WORKDIR /code

# Install system dependencies needed for the project
RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y python3 python3-pip python3-dev netcat-openbsd wget build-essential \
    libffi-dev libpango1.0-0 libpangocairo-1.0-0 libcairo2 libjpeg-dev \
    zlib1g-dev libxml2 libxslt1.1 libgdk-pixbuf2.0-0 unzip

# Upgrade pip and install the Python dependencies from requirements.txt
RUN pip3 install --upgrade pip
COPY requirements.txt .
RUN pip3 install -r requirements.txt

# Copy the project files into the container
COPY . .

# Set executable permissions for the entrypoint script
RUN chmod +x /code/entrypoint.sh

# Command to run when the container starts
ENTRYPOINT ["/bin/sh", "/code/entrypoint.sh"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;my docker-compose.yml was like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
services:
  web:
    build: .
    command: /code/entrypoint.sh
    volumes:
      - .:/code
      - static_volume:/code/staticfiles
    ports:
      - '8000:8000'
    env_file: .env
    depends_on:
      - db
    environment:
      - DB_HOST=db

  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data
    env_file: .env
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    ports:
      - '5434:5432'
  nginx:
    image: nginx:alpine
    ports:
      - '80:80'
    volumes:
      - static_volume:/code/staticfiles
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - web

volumes:
  postgres_data:
  static_volume:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And my entrypoint.sh was like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh

# Set the Django settings module
export DJANGO_SETTINGS_MODULE=businesshub.settings

# Wait for the database to be ready
echo "⏳ Waiting for the database at $DB_HOST..."
retries=10
while ! nc -z $DB_HOST 5432; do
  retries=$((retries-1))
  if [ $retries -eq 0 ]; then
    echo "❌ Timeout: Unable to connect to the database!"
    exit 1
  fi
  sleep 1
done
echo "✅ Database is available!"

set -e

# Create migrations if there are any changes to models
echo "🔄 Creating migrations..."
python3 manage.py makemigrations

# Apply database migrations
echo "🔄 Applying database migrations..."
python3 manage.py migrate

# Check if Django is running in DEBUG mode
DEBUG_MODE=$(python3 -c "from django.conf import settings; print(settings.DEBUG)")

# If in production, collect static files and start the Gunicorn server
if [ "$DEBUG_MODE" = "False" ]; then
  echo "📦 Collecting static files (production only)..."
  python3 manage.py collectstatic --noinput

  echo "🚀 Starting Gunicorn server..."
  exec gunicorn businesshub.wsgi:application \
    --bind 0.0.0.0:8000 \
    --workers 3 \
    --timeout 120
else
  # If in DEBUG mode, start the Django development server
  echo "⚙️  DEBUG mode: starting Django development server..."
  exec python3 manage.py runserver 0.0.0.0:8000
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, I use some AI help to comment these files.&lt;/p&gt;

&lt;p&gt;At this point, I had the idea to integrate Jasper Reports in order to create some reports. Usually, you can use something like ReportLabs, but I wanted to create reports with Jasper Studio, put them into my container, and call them with some Django view.&lt;/p&gt;

&lt;p&gt;So, I started to search for some documentation to understand how to do this. The best way seemed to be using Jasper Server and interacting with it through API calls. However, I found that Jasper Server is no longer available in a free version, which made things a bit tricky. The commercial version requires a license, and while there are some alternatives, I couldn’t find a free solution that would integrate well with my current setup.&lt;/p&gt;

&lt;p&gt;Instead of using Jasper Server, I ended up integrating JasperReports directly into my Docker container, using a custom Java helper to generate reports. This way, I could still leverage the powerful report generation features of Jasper without relying on an external server, which simplified the architecture and saved some overhead. In order to do this, I used Django subprocess.&lt;br&gt;
First of all you need to download Jasper Report libraries. So I change my Dockerfile in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:11-jdk-slim

# Environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Set the working directory inside the container
WORKDIR /code

# Install system dependencies needed for the project
RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y python3 python3-pip python3-dev netcat-openbsd wget build-essential \
    libffi-dev libpango1.0-0 libpangocairo-1.0-0 libcairo2 libjpeg-dev \
    zlib1g-dev libxml2 libxslt1.1 libgdk-pixbuf2.0-0 unzip

# Upgrade pip and install the Python dependencies from requirements.txt
RUN pip3 install --upgrade pip
COPY requirements.txt .
RUN pip3 install -r requirements.txt

# Copy the project files into the container
COPY . .

# Copy jreports folder with .jasper e .jrxml files
COPY jreports /code/jreports

# Create the folder for JasperReports JAR 
RUN mkdir -p /opt/jasperreports/lib

# Download JasperReports 7.0.2 and dependencies
RUN wget https://repo1.maven.org/maven2/net/sf/jasperreports/jasperreports/7.0.2/jasperreports-7.0.2.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/jfree/jfreechart/1.5.3/jfreechart-1.5.3.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/jfree/jcommon/1.0.23/jcommon-1.0.23.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/kernel/7.1.16/kernel-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/io/7.1.16/io-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/layout/7.1.16/layout-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/forms/7.1.16/forms-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/pdfa/7.1.16/pdfa-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/sign/7.1.16/sign-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/barcodes/7.1.16/barcodes-7.1.16.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/eclipse/jdt/ecj/3.21.0/ecj-3.21.0.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/commons-digester/commons-digester/2.1/commons-digester-2.1.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/commons-beanutils/commons-beanutils/1.9.4/commons-beanutils-1.9.4.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.30/slf4j-simple-1.7.30.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/net/sf/jasperreports/jasperreports-pdf/7.0.2/jasperreports-pdf-7.0.2.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/itextpdf/commons/7.2.0/commons-7.2.0.jar -P /opt/jasperreports/lib/ &amp;amp;&amp;amp; \
    wget https://repo1.maven.org/maven2/com/github/librepdf/openpdf/1.3.30/openpdf-1.3.30.jar -P /opt/jasperreports/lib/


# Copy ReportGenerator.java 
COPY ReportGenerator.java /opt/jasperreports/

# Compile ReportGenerator.java file
RUN cd /opt/jasperreports &amp;amp;&amp;amp; \
    javac -cp "lib/*" ReportGenerator.java &amp;amp;&amp;amp; \
    mkdir -p classes &amp;amp;&amp;amp; \
    mv ReportGenerator.class classes/

RUN wget https://jdbc.postgresql.org/download/postgresql-42.5.0.jar -O /opt/jasperreports/lib/postgresql-42.5.0.jar

RUN chmod +x /code/entrypoint.sh

# Comando di avvio del container
ENTRYPOINT ["/bin/sh", "/code/entrypoint.sh"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I had to change the base image from &lt;br&gt;
FROM python:3.11-slim &lt;br&gt;
to &lt;br&gt;
FROM openjdk:11-jdk-slim &lt;br&gt;
because JasperReports relies on Java to function. The original Python image doesn't include the necessary Java runtime environment, which is required by JasperReports to generate reports.&lt;/p&gt;

&lt;p&gt;JasperReports is a Java-based reporting tool, so it needs the Java Development Kit (JDK) to run properly. The Python image, while great for running Python applications, doesn't come with Java installed, and without it, JasperReports wouldn't be able to work. By switching to an image that already includes OpenJDK, we ensure that we have the necessary Java environment to run the JasperReports library and its dependencies.&lt;br&gt;
Then, I created a folder called jreports where I stored my .jrxml and .jasper files that I created with Jasper Studio. Using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY jreports /code/jreports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I copied them into the container folder. Next, I created a directory to store the required dependencies with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN mkdir -p /opt/jasperreports/lib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now comes the hardest part: finding and downloading the correct dependencies. This was the most challenging task. It wasn't easy to find the right versions, and I spent a lot of time searching through forums and documentation for solutions. I spent quite some time troubleshooting with the help of ChatGPT and Claude. They kept suggesting dependencies and versions that blocked the Docker build because the files were nonexistent or the paths were incorrect. So with a lot of patience, finally I came to a list that works. &lt;br&gt;
The next step was to integrate my ReportGenerator.java file into the container. ReportGenerator.java is the one that makes possible to use Jasper in Django. This is the file that I call when I need to build the report.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ReportGenerator.java
import net.sf.jasperreports.engine.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

public class ReportGenerator {
    public static void main(String[] a# Imposta i permessi di esecuzione per entrypoint.shrgs) {
        try {
            if (args.length &amp;lt; 6) {
                System.err.println(
                        "Usage: java ReportGenerator &amp;lt;template_path&amp;gt; &amp;lt;output_path&amp;gt; &amp;lt;db_url&amp;gt; &amp;lt;db_user&amp;gt; &amp;lt;db_password&amp;gt; [param1=value1 param2=value2 ...]");
                System.exit(1);
            }

            String templatePath = args[0];
            String outputPath = args[1];
            String dbUrl = args[2];
            String dbUser = args[3];
            String dbPassword = args[4];

            System.out.println("Template path: " + templatePath);
            System.out.println("Output path: " + outputPath);
            System.out.println("Database URL: " + dbUrl);

            Map&amp;lt;String, Object&amp;gt; parameters = new HashMap&amp;lt;&amp;gt;();
            for (int i = 5; i &amp;lt; args.length; i++) {
                String[] param = args[i].split("=", 2);
                if (param.length == 2) {
                    if (param[0].equals("PK")) {
                        try {
                            long pkValue = Long.parseLong(param[1]);
                            parameters.put(param[0], pkValue);
                            System.out.println("Parameter: " + param[0] + " = " + pkValue + " (Long)");
                        } catch (NumberFormatException e) {
                            System.err.println("Error: PK parameter must be a number");
                            System.exit(1);
                        }
                    } else {
                        parameters.put(param[0], param[1]);
                        System.out.println("Parameter: " + param[0] + " = " + param[1]);
                    }
                }
            }

            Class.forName("org.postgresql.Driver");
            System.out.println("PostgreSQL JDBC driver loaded.");

            Connection connection = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
            System.out.println("Database connection established.");

            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery(
                    "SELECT id, numero_interno, plafond FROM documenti_dichiarazioneintento WHERE id = "
                            + parameters.get("PK"));
            if (rs.next()) {
                System.out.println("Record found: ID=" + rs.getLong("id") +
                        ", numero_interno=" + rs.getInt("numero_interno") +
                        ", plafond=" + rs.getBigDecimal("plafond"));
            } else {
                System.out.println("No records found with PK=" + parameters.get("PK"));
            }
            rs.close();
            stmt.close();

            System.out.println("Filling report with parameters: " + parameters);
            JasperPrint jasperPrint = JasperFillManager.fillReport(templatePath, parameters, connection);

            System.out.println("Report compiled successfully.");
            System.out.println("Number of pages: " + jasperPrint.getPages().size());

            JasperExportManager.exportReportToPdfFile(jasperPrint, outputPath);
            System.out.println("Report generated successfully: " + outputPath);

            connection.close();
            System.exit(0);
        } catch (Exception e) {
            System.err.println("Error generating report: " + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ReportGenerator.java class plays a critical role in generating the JasperReports PDF report in this setup. It acts as a bridge between your Django application and the JasperReports engine. Let’s break down its functionality and how it integrates with the Django project.&lt;/p&gt;

&lt;p&gt;Key Components of ReportGenerator.java:&lt;br&gt;
Dependencies and Libraries: The class uses various Java libraries, most notably the JasperReports library itself, as well as JDBC for database connectivity. These libraries allow the class to:&lt;/p&gt;

&lt;p&gt;Fill the report with data fetched from the database.&lt;/p&gt;

&lt;p&gt;Export the report to a PDF file.&lt;/p&gt;

&lt;p&gt;Handle parameters passed by the Django application (e.g., the primary key PK of the record).&lt;/p&gt;

&lt;p&gt;Here’s how the dependencies are integrated:&lt;/p&gt;

&lt;p&gt;JasperReports Engine (net.sf.jasperreports.engine): This is the core library for compiling, filling, and exporting reports.&lt;/p&gt;

&lt;p&gt;PostgreSQL JDBC Driver (org.postgresql.Driver): Used for establishing a connection with the PostgreSQL database to fetch the data needed for the report.&lt;/p&gt;

&lt;p&gt;Main Method: The main method is where the process of generating the report begins. This method accepts several arguments:&lt;/p&gt;

&lt;p&gt;templatePath: The path to the Jasper template file (.jasper).&lt;/p&gt;

&lt;p&gt;outputPath: The path where the generated PDF report will be saved.&lt;/p&gt;

&lt;p&gt;dbUrl, dbUser, dbPassword: Credentials and URL for connecting to the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Additional parameters: These can be dynamic parameters that the report template expects, such as a specific PK (primary key) value to fetch the correct data.&lt;/p&gt;

&lt;p&gt;Parameter Handling:&lt;/p&gt;

&lt;p&gt;The class accepts dynamic parameters as command-line arguments (e.g., PK=12345).&lt;/p&gt;

&lt;p&gt;These parameters are parsed and added to a Map, which is passed to the JasperReports engine when filling the report. This allows you to customize the report’s content based on the provided values.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;The PK parameter is particularly important. It represents the primary key of a specific record, and based on this key, the corresponding record is fetched from the database to populate the report.&lt;/p&gt;

&lt;p&gt;Database Connection:&lt;/p&gt;

&lt;p&gt;The class connects to the PostgreSQL database using the provided JDBC URL and credentials.&lt;/p&gt;

&lt;p&gt;A Statement is created to execute an SQL query to fetch the necessary data for the report. In this case, the SQL query looks for a specific record in the documenti_dichiarazioneintento table by matching the PK value.&lt;/p&gt;

&lt;p&gt;Example query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT id, numero_interno, plafond FROM documenti_dichiarazioneintento WHERE id = ?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the record exists, it’s used to populate the report parameters; if not, an error message is displayed.&lt;/p&gt;

&lt;p&gt;Filling the Report:&lt;/p&gt;

&lt;p&gt;Once the data is retrieved from the database, the JasperFillManager.fillReport() method is called. This method takes the compiled .jasper file, the parameters, and the database connection to generate a filled report (JasperPrint object).&lt;/p&gt;

&lt;p&gt;The JasperPrint object contains all the content of the report, including text, images, and dynamic data from the database.&lt;/p&gt;

&lt;p&gt;Exporting the Report:&lt;/p&gt;

&lt;p&gt;After the report is filled with the required data, it is exported to a PDF file using the JasperExportManager.exportReportToPdfFile() method.&lt;/p&gt;

&lt;p&gt;The generated PDF is then saved to the outputPath location, which can be returned to the user through the Django view.&lt;/p&gt;

&lt;p&gt;Error Handling:&lt;/p&gt;

&lt;p&gt;The class includes basic error handling. If there’s an issue generating the report (e.g., if the database connection fails or if the report template is invalid), the error is caught, and an error message is printed.&lt;/p&gt;

&lt;p&gt;Integration with Django:&lt;br&gt;
Calling the Java Class: From Django, you invoke the ReportGenerator Java class by using the subprocess.run() method. This allows you to run Java commands as if they were shell commands, passing the required parameters like the template path, output path, database URL, and credentials.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
command = [
    "java",
    "-cp",
    "/opt/jasperreports/classes:/opt/jasperreports/lib/*",
    "ReportGenerator",
    report_path,
    output_path,
    db_url,
    db_user,
    db_password,
    f"PK={pk}",  # Pass PK parameter
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command is constructed with the appropriate classpath (-cp), which includes the necessary JAR files for JasperReports and PostgreSQL JDBC. Then the Java class (ReportGenerator) is invoked with the parameters passed in the correct order.&lt;/p&gt;

&lt;p&gt;Parameters:&lt;/p&gt;

&lt;p&gt;When the Django view is called (in this case, dichiarazione_intento), it passes the PK value for the document to be included in the report.&lt;/p&gt;

&lt;p&gt;This PK value is used in the SQL query inside ReportGenerator.java to fetch the correct record from the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Subprocess Execution:&lt;/p&gt;

&lt;p&gt;The Java process is executed in the background, and once it finishes, the generated PDF is saved to a file.&lt;/p&gt;

&lt;p&gt;The view then reads the generated PDF and returns it to the user as a response.&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
The ReportGenerator.java class is essential for integrating JasperReports with Django. It acts as the backend logic for compiling, filling, and exporting the report based on dynamic parameters and database queries. This integration leverages Java's powerful reporting capabilities while allowing Django to trigger the report generation process via subprocess calls.&lt;/p&gt;

&lt;p&gt;By separating the report generation into a standalone Java class, you maintain flexibility and modularity in the design. JasperReports remains a powerful and customizable tool for generating complex reports, and this solution allows you to use it seamlessly within a Django application.&lt;/p&gt;

&lt;p&gt;So I copy this in my container with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY ReportGenerator.java /opt/jasperreports/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and compile it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN cd /opt/jasperreports &amp;amp;&amp;amp; \
    javac -cp "lib/*" ReportGenerator.java &amp;amp;&amp;amp; \
    mkdir -p classes &amp;amp;&amp;amp; \
    mv ReportGenerator.class classes/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I download postgresql java dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN wget https://jdbc.postgresql.org/download/postgresql-42.5.0.jar -O /opt/jasperreports/lib/postgresql-42.5.0.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, maybe I can put this wget with others? I will try.&lt;/p&gt;

&lt;p&gt;Finally I start my entrypoint.sh file.&lt;/p&gt;

&lt;p&gt;So, at this point my project will be like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;businesshub/
   |_ accounts
   |_ anagrafiche
   |_ businesshub
   |_ core
   |_ documents
   |_ jreports
      |_DichIntento.jasper
      |_DichIntento.jrxml
   |_ nginx
      |_default.conf
   |_ templates
.env
.env.prod
docker-compose.yml
Dockerfile
entrypoint.sh
manage.py
ReportGenerator.java
requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the view to call my report is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess
from django.http import HttpResponse
from django.conf import settings
import os
from documenti.models import DichiarazioneIntento


def dichiarazione_intento(request, pk):
    # Paths
    report_path = "/code/jreports/DichIntento.jasper"
    output_path = "/code/jreports/output_report.pdf"

    # Get database credentials from environment variables
    db_host = os.environ.get("DB_HOST", "localhost")
    db_port = os.environ.get("DB_PORT", "5432")
    db_user = os.environ.get("POSTGRES_USER", "postgres")
    db_password = os.environ.get("POSTGRES_PASSWORD", "")
    db_name = os.environ.get("POSTGRES_DB", "postgres")

    # Create JDBC URL
    db_url = f"jdbc:postgresql://{db_host}:{db_port}/{db_name}"

    # Get the object to verify it exists
    dichiarazione = DichiarazioneIntento.objects.get(pk=pk)
    print(f"dichiarazione: {dichiarazione.data_dichiarazione}")
    print(f"Generating report with PK: {pk}")

    # Build Java command
    command = [
        "java",
        "-cp",
        "/opt/jasperreports/classes:/opt/jasperreports/lib/*",
        "ReportGenerator",
        report_path,
        output_path,
        db_url,
        db_user,
        db_password,
        f"PK={pk}",  # Pass PK parameter
    ]

    print(f"Executing command: {' '.join(command)}")

    # Execute Java command
    try:
        result = subprocess.run(
            command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
        )
        print(f"Output: {result.stdout.decode()}")
    except subprocess.CalledProcessError as e:
        error_message = e.stderr.decode() if e.stderr else str(e)
        print(f"Error: {error_message}")
        return HttpResponse(f"Error generating report: {error_message}", status=500)

    # Verify file exists
    if not os.path.exists(output_path):
        return HttpResponse("Generated PDF file not found", status=500)


    with open(output_path, "rb") as pdf_file:
        response = HttpResponse(pdf_file.read(), content_type="application/pdf")
        response["Content-Disposition"] = 'inline; filename="report.pdf"'
        return response

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that everything is set up, I can start using JasperReports in my Django project. This experience taught me a lot about integrating Java-based tools into a Python/Django environment, and I'm excited to explore more reporting features in the future.&lt;/p&gt;

&lt;p&gt;Thank you for reading through this entire guide! I hope you found it helpful and that it provides valuable insights into integrating JasperReports with Django in a Dockerized environment. If you have any questions, suggestions, or tips to improve this process, feel free to leave a comment below—I’d love to hear from you!&lt;/p&gt;

&lt;p&gt;If you're interested in learning more about Django, Docker, or JasperReports, make sure to follow me for future updates and more detailed tutorials. Happy coding!&lt;/p&gt;

</description>
      <category>jasperreports</category>
      <category>django</category>
      <category>docker</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Add toast notification with Django - an easy way</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Tue, 23 Apr 2024 13:48:27 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/add-toast-notification-with-django-an-easy-way-148o</link>
      <guid>https://forem.com/rquattrogtl/add-toast-notification-with-django-an-easy-way-148o</guid>
      <description>&lt;p&gt;I was working on an app with a scheduling feature and I needed a toast notification system to inform users about some deadlines. There are some different ways to achieve this goal.&lt;br&gt;
If you are using Bootstrap, you can use his toast classes and a little bit of JavaScript.&lt;/p&gt;
&lt;h2&gt;
  
  
  Start the new project
&lt;/h2&gt;

&lt;p&gt;So let's open a new directory in our favourite editor:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzo6a29kh56hb98dq76ee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzo6a29kh56hb98dq76ee.png" alt="VSCode new Django project" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create a new venv with&lt;br&gt;
&lt;code&gt;python3 -m venv venv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activate the new venv. I'm on a linux machine so:&lt;br&gt;
&lt;code&gt;source venv/bin/activate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install Django:&lt;br&gt;
&lt;code&gt;pip install django&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create our project:&lt;br&gt;
&lt;code&gt;django-admin startproject toast&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Move on new directory:&lt;br&gt;
&lt;code&gt;cd toast&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And create a new app:&lt;br&gt;
&lt;code&gt;python manage.py startapp toast_notifications&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, now we should have this structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45pz9ufmtt61mwjv8svq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45pz9ufmtt61mwjv8svq.png" alt="VSCode Django structure" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if we start our development server and go to &lt;a href="http://127.0.0.1:8000/"&gt;http://127.0.0.1:8000/&lt;/a&gt; in our browser, we should have this message:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwhbizhvpsoburlkktru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwhbizhvpsoburlkktru.png" alt="Django development server" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now add our app in the settings.py file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'toast_notifications',
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice!&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Models
&lt;/h2&gt;

&lt;p&gt;Now we can create our models. Let's suppose that we need a scheduler to manage equipment maintenance. So we need a model for tools, and in the model.py file of our app we can create it in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Tool(models.Model):
    tool_code = models.CharField(max_length=10)
    description= models.CharField(max_length=50)    
    serial = models.CharField(max_length=50, null=True, blank=True)          
    note = models.TextField(null=True, blank=True)    
    created_at = models.DateTimeField(auto_now_add=True)

     def __str__(self):        
        return f"Tool Code: {self.tool_code} - Description: {self.description}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may need other fields for your tool (i.e. an image or a field to get where the tool is stored...), but for our purpose, those fields are enough.&lt;/p&gt;

&lt;p&gt;Now, let's create the model for maintenance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Maintenance(models.Model):
    fk_tool = models.ForeignKey(Tool, on_delete=models.CASCADE)
    maintenance_date = models.DateField(null=False, blank=False)
    description= models.CharField(max_length=100)        
    next_schedule = models.DateField(null=False, blank=False)
    note = models.TextField(null=True, blank=True)    
    created_at = models.DateTimeField(auto_now_add=True)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we need to put our attention to next_schedule field that will give us the the date for our toast.&lt;/p&gt;

&lt;p&gt;Let's migrate our models with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python manage.py makemigrations
python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we should have this structure&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnmcdrnnj5prx14p9r48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnnmcdrnnj5prx14p9r48.png" alt="vscode django structure" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create views
&lt;/h2&gt;

&lt;p&gt;Now we can create our view. We need to filter our model in order to get only maintenance with next_schedule greater than or equal to today's date. Let's suppose that we need to view in our toasts only the maintenance of the next 30 days. &lt;br&gt;
So, our view could be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from datetime import date, timedelta
from django.shortcuts import render
from .models import *

def home(request):
    today = date.today()
    thirty_days_from_today = today + timedelta(days=30)
    maintenance_scheduler = Maintenance.objects.filter(next_schedule__gte=today).filter(next_schedule__lte=thirty_days_from_today)
    context = {       
        'maintenance_scheduler':maintenance_scheduler
    }
    return render(request, 'toast_notifications/home.html', context)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to set our templates path in settings.py file in the toast folder. So in the settings.py file we add the directory of templates for our app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            (BASE_DIR /'toast_notifications' / 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok. Now in our toast_notifications directory, create new folder "template"; in this folder create new folder "toast_notifications". In this folder create a new file "home.html".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvt5xop4xkarjfjt9cvr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvt5xop4xkarjfjt9cvr.png" alt="vscode django template structure" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to create our URL path. In urls.py file in toast folder, we can add our path, but first we have to import our view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
from django.contrib import admin
from django.urls import path
from toast_notifications.views import home

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home, name='home'),
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we are ready for the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the template
&lt;/h2&gt;

&lt;p&gt;For the template we can use bootstrap at this link&lt;br&gt;
&lt;a href="https://getbootstrap.com/docs/5.3/getting-started/introduction/"&gt;Bootstrap getting-started&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the code in the second step and paste it in your home.html file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
    &amp;lt;title&amp;gt;Bootstrap demo&amp;lt;/title&amp;gt;
    &amp;lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello, world!&amp;lt;/h1&amp;gt;
    &amp;lt;script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try it. give the command &lt;br&gt;
&lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;br&gt;
and if you don't get any errors, you should find your hello world page in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b1mycdjhepczdepm4cs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b1mycdjhepczdepm4cs.png" alt="Bootstrap hello world page" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create some instances
&lt;/h2&gt;

&lt;p&gt;Let'create some instances. In the terminal give the command:&lt;br&gt;
&lt;code&gt;python manage.py shell&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and then:&lt;br&gt;
&lt;code&gt;from toast_notifications.models import Tool&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we can create our Tool instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tool1 = Tool.objects.create(tool_code='Code1', description='Description1', serial='Serial1', note='Note1')
tool2 = Tool.objects.create(tool_code='Code2', description='Description2', serial='Serial2', note='Note2')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same thing for Maintenance instances:&lt;br&gt;
&lt;code&gt;from toast_notifications.models import Maintenance&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maintenance1 = Maintenance.objects.create(fk_tool=tool1, maintenance_date='2024-04-23', description='Description 1', next_schedule='2024-04-30', note='Note 1')
maintenance2 = Maintenance.objects.create(fk_tool=tool2, maintenance_date='2024-04-23', description='Description 2', next_schedule='2024-05-30', note='Note 2')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok. Now to have a check we can put our instances in our template adding these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="container"&amp;gt;
        {% for schedule in maintenance_scheduler %}

            &amp;lt;p&amp;gt;{{ schedule.fk_tool }} - next schedule: {{ schedule.next_schedule }} &amp;lt;/p&amp;gt;
        {% endfor %}
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;under the "Hello world" line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdi0fb0plipuzn5mq6hwr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdi0fb0plipuzn5mq6hwr.png" alt="django template with variables" width="800" height="406"&gt;&lt;/a&gt;&lt;br&gt;
So, we can see only one instance, because of our "thirty_days_from_today" filter. Our toast must show the same result.&lt;/p&gt;
&lt;h2&gt;
  
  
  Toast
&lt;/h2&gt;

&lt;p&gt;Bootstrap toast component can be found at this link&lt;br&gt;
&lt;a href="https://getbootstrap.com/docs/5.3/components/toasts/"&gt;Bootstrap toasts&lt;/a&gt;&lt;br&gt;
You can find different versions based on what you need but toast can be customized as well.&lt;/p&gt;

&lt;p&gt;Our toasts could be multiple so we have to put them in a toast container. Moreover, we can loop through our variables to create our toasts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="toast-container position-fixed bottom-0 end-0 p-3"&amp;gt;
    {% for schedule in maintenance_scheduler %}
  &amp;lt;div id="liveToast{{ schedule.pk }}" class="toast" role="alert" aria-live="assertive" aria-atomic="true"&amp;gt;
    &amp;lt;div class="toast-header"&amp;gt;

      &amp;lt;strong class="me-auto"&amp;gt;Hi! I'm a toast!&amp;lt;/strong&amp;gt;
      &amp;lt;small&amp;gt;maintenance scheduler&amp;lt;/small&amp;gt;
      &amp;lt;button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"&amp;gt;&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="toast-body"&amp;gt;
      {{ schedule.fk_tool }} - next schedule: {{ schedule.next_schedule }}
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  {% endfor %}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A very little piece of JavaScript
&lt;/h2&gt;

&lt;p&gt;We could have a lot of different needs in order to show our toasts. If we suppose that we need them when we open the page, than we can put on the bottom of our template a very simple script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script&amp;gt;
        document.addEventListener("DOMContentLoaded", function() {
        var toasts = document.querySelectorAll('.toast');
        toasts.forEach(function(toast) {
            new bootstrap.Toast(toast).show();
        });
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this script, we ask for show our toasts when the DOM content is loaded. &lt;/p&gt;

&lt;p&gt;Let's take a look to our whole template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
    &amp;lt;title&amp;gt;Bootstrap demo&amp;lt;/title&amp;gt;
    &amp;lt;link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;


    &amp;lt;h1&amp;gt;Hello, world!&amp;lt;/h1&amp;gt;
    &amp;lt;div class="container"&amp;gt;
        {% for schedule in maintenance_scheduler %}

            &amp;lt;p&amp;gt;{{ schedule.fk_tool }} - next schedule: {{ schedule.next_schedule }} &amp;lt;/p&amp;gt;
        {% endfor %}
    &amp;lt;/div&amp;gt;

&amp;lt;div class="toast-container position-fixed bottom-0 end-0 p-3"&amp;gt;
    {% for schedule in maintenance_scheduler %}
  &amp;lt;div class="toast" role="alert" aria-live="assertive" aria-atomic="true"&amp;gt;
    &amp;lt;div class="toast-header"&amp;gt;

      &amp;lt;strong class="me-auto"&amp;gt;Hi! I'm a toast!&amp;lt;/strong&amp;gt;
      &amp;lt;small&amp;gt;maintenance scheduler&amp;lt;/small&amp;gt;
      &amp;lt;button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"&amp;gt;&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="toast-body"&amp;gt;
      {{ schedule.fk_tool }} - next schedule: {{ schedule.next_schedule }}
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
  {% endfor %}
&amp;lt;/div&amp;gt;




    &amp;lt;script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"&amp;gt;&amp;lt;/script&amp;gt;

    &amp;lt;script&amp;gt;
        document.addEventListener("DOMContentLoaded", function() {
        var toasts = document.querySelectorAll('.toast');
        toasts.forEach(function(toast) {
            new bootstrap.Toast(toast).show();
        });
});
&amp;lt;/script&amp;gt;

  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frukdb6h9uw3sy9odb49c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frukdb6h9uw3sy9odb49c.png" alt="bootstrap with toast notification" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a very simple toast. In my app, toasts are full of other informations, like a URL link to go view the right tool, who is the technician to call and so on. &lt;/p&gt;

&lt;p&gt;If you are working with React or Vue for example, you can find other ways to use toasts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Toasts can be an interesting way to show some information to users. This was a very simple way to use them. &lt;br&gt;
Feel free to drop a suggestion or a comment.&lt;br&gt;
Thanks for reading! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>django</category>
      <category>bootstrap</category>
    </item>
    <item>
      <title>Django Environment Variables</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Tue, 10 Oct 2023 09:05:32 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/django-environment-variables-2b8o</link>
      <guid>https://forem.com/rquattrogtl/django-environment-variables-2b8o</guid>
      <description>&lt;h2&gt;
  
  
  Why do you need to use Environment Variables?
&lt;/h2&gt;

&lt;p&gt;When you are building some Django project, you will need variables to manage, for example, database configuration, or to set the Debug option as True or False, especially when working with a project deployed in production that needs implementation. &lt;/p&gt;

&lt;p&gt;There are some packages that can help you out there, but personally, I use &lt;a href="https://django-environ.readthedocs.io/en/latest/index.html"&gt;django-environ&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use django-environ and .env file
&lt;/h2&gt;

&lt;p&gt;First of all, you need to install the package in your virtual environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install django-environ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to freeze your packages list with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to understand how pip freeze works, you can take a look on these good posts:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://dev.to/eskabore/pip-freeze-requirementstxt-a-beginners-guide-5e2m"&gt;Pip Freeze &amp;gt; Requirements.txt: A Beginner's Guide&lt;/a&gt; by &lt;a href="https://dev.to/eskabore"&gt;Jean-Luc KABORE-TURQUIN&lt;/a&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://dev.to/exactful/how-to-avoid-python-dependency-hell-with-venv-and-pip-freeze-1k0h"&gt;Virtual environments: How to avoid Python dependency hell with venv and pip freeze&lt;/a&gt; by &lt;a href="https://dev.to/exactful"&gt;Daniel Cooper&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Now, you need to create a .env file where you will put all the variables you need. Let's see how you can build it.&lt;br&gt;
First of all, you need to create the file, usually in the base directory of your project. Usually, the first variable I put in the .env file is the DEBUG option and SECRET_KEY.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env file
DEBUG=True
SECRET_KEY='your-secret-key'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, now we have our first environment variable. Let's see how we can use it.&lt;br&gt;
We need to open our settings.py file and change something. First of all, we need to import our package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# settings.py file
[...]
import environ
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


env = environ.Env(
    # set casting, default value
    DEBUG=(bool, False)
)


# Take environment variables from .env file
environ.Env.read_env(BASE_DIR / '.env')

# We are taking our secret key from .env file
SECRET_KEY = env('SECRET_KEY')

# Get from .env file if we are debugging or not
DEBUG = env('DEBUG')

[...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first step, but you can get more variables using this method. Other important variables I usually put in .env are variables for database. Let's take again our .env file and add our database variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env file
DEBUG=True
SECRET_KEY='your-secret-key'
DATABASE_TYPE=sqlite
SQLITE_DB_PATH=db.sqlite3
POSTGRES_DB_NAME=
POSTGRES_DB_USER=
POSTGRES_DB_PASSWORD=
POSTGRES_DB_HOST=
POSTGRES_DB_PORT=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, I put both SQLite and PostgreSQL variables. I manage these variables in my settings.py file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# settings.py file
[...]

SQLITE_DB_PATH =  os.path.join(BASE_DIR, env('SQLITE_DB_PATH'))
if env('DATABASE_TYPE') == 'sqlite':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': SQLITE_DB_PATH,
        }
    }
elif env('DATABASE_TYPE') == 'postgresql':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': env('POSTGRES_DB_NAME'),
            'USER': env('POSTGRES_DB_USER'),
            'PASSWORD': env('POSTGRES_DB_PASSWORD'),
            'HOST': env('POSTGRES_DB_HOST'),
            'PORT': env('POSTGRES_DB_PORT'),
        }
    }
else:
    raise ValueError("Unknown database type specified in DATABASE_TYPE.")
[...]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, I used the default SQLite database, but is enough to put 'postgresql' in the DATABASE_TYPE variable in the .env file to switch to Postgres (settings postgres variables, obviously).&lt;/p&gt;

&lt;p&gt;These are some cases when you can use environment variables. You can also set the STATIC_ROOT path as variables, for example. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tip
&lt;/h2&gt;

&lt;p&gt;Make sure you add .env file in you gitignore file, in order to avoid to push your private variables in your repository. A better idea is to create a .env.example file, where you put your variables without values. In our case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .env.example file
DEBUG=
SECRET_KEY=
DATABASE_TYPE=
SQLITE_DB_PATH=
POSTGRES_DB_NAME=
POSTGRES_DB_USER=
POSTGRES_DB_PASSWORD=
POSTGRES_DB_HOST=
POSTGRES_DB_PORT=
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in this way, you'll help to understand how your environment variables system works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;This is how I manage environment variables. I hope this will help. If you have any suggestions, feel free to comment.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Django: timedelta, DurationField and Total Time</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Thu, 24 Mar 2022 15:41:14 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/django-timedelta-durationfield-and-total-time-d51</link>
      <guid>https://forem.com/rquattrogtl/django-timedelta-durationfield-and-total-time-d51</guid>
      <description>&lt;p&gt;Some months ago, I had to do some operations with my Model's date fields. I search for solutions and I found some useful python packages. So I will share those solutions. I will share also the github repository. &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating project
&lt;/h2&gt;

&lt;p&gt;I create a project folder called Datefunctionsproject and I started a project called mydateproject&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk46z8g32vo5ulkc31mg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk46z8g32vo5ulkc31mg0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;then I navigate into my project folder and I create mydateapp. After this, I made migrations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0ac9dl3kaynihsso5bp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0ac9dl3kaynihsso5bp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I create superuser...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fij4qwkpa08lfjhgd4ouw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fij4qwkpa08lfjhgd4ouw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;...and added my app to installed apps in settings.py&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrr9jkwb8p5zztxivnh7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrr9jkwb8p5zztxivnh7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally check if is all ok running server...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7pzc3l3ggtc2cq6i7s0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7pzc3l3ggtc2cq6i7s0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a basic template
&lt;/h2&gt;

&lt;p&gt;We need a basic template. To do this, we can create a new folder on mydateapp folder called "templates" and inside this we create a new file called "index.html":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcakukzo90oa4usm2luj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcakukzo90oa4usm2luj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we have to set the path of our templates in the file "settings.py" under "TEMPLATES" section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesr0p9lu12lfd42vjxxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesr0p9lu12lfd42vjxxo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Model
&lt;/h2&gt;

&lt;p&gt;We can create a basic Model to see the behaviour of our time fields. So in models.py in mydateapp, we will create this model:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from django.db import models

# Create your models here.

class Times(models.Model):
    my_date = models.DateField()
    start_time=models.TimeField()
    end_time=models.TimeField()


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We can build our basic view. We will build it better going ahead. So, in our views.py file in mydateapp folder, we will have:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from django.shortcuts import render
from .models import Times
# Create your views here.

def home_view(request):
    return render(request, "index.html")


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we can register our model in order to work with it in admin section. To do this, we can register it in admin.py file in mydateapp folder we will have:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from django.contrib import admin
from .models import Times

# Register your models here.

admin.site.register(Times)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Setup of urls.py files
&lt;/h2&gt;

&lt;p&gt;In the urls.py file of the project, we can include the urls of our app:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('mydateapp.urls')),
]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then in the mydateapp folder, we must create a new file called urls.py and write down some stuff like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from django.urls import path
from .views import home_view

urlpatterns = [
    path('', home_view, name="home_view"),
]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Adding some records
&lt;/h2&gt;

&lt;p&gt;At his point, we must run &lt;br&gt;
python manage.py makemigrations&lt;br&gt;
python manage.py migrate&lt;br&gt;
in order to create the table in our database.&lt;/p&gt;

&lt;p&gt;Now, we are ready to try some stuff. First of all, launching python manage.py runserver command, we will see if everything is ok and we should see our index.html page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwqeylunlbgfs4uixybi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwqeylunlbgfs4uixybi.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if we add /admin to the path, we should be asked for user and password:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5diawh55583iq4v3tjmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5diawh55583iq4v3tjmi.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Type them and you will see the admin panel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft8jybg1dczhcrnr0bmed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft8jybg1dczhcrnr0bmed.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on our model and then on "Add" button. You will be able to add some new records. Pay attention to put correct data in there, because we haven't used a control system to check if start_time is greater than end_time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zci27g1c5s49ygwsrcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zci27g1c5s49ygwsrcx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, I created 3 records:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrs0pwek639ws9da0zoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrs0pwek639ws9da0zoq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Start playing with times and dates
&lt;/h2&gt;

&lt;p&gt;Finally, we are ready to play. &lt;br&gt;
The first thing we can do is to build a simple table that shows our records. First of all in our views.py file, we have to import some modules:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from django.utils import timezone
from django.db.models import F, DurationField, Sum, ExpressionWrapper
from datetime import datetime, time, timedelta


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;timezone: When time zone support is enabled (USE_TZ=True), Django uses time-zone-aware datetime objects. If your code creates datetime objects, they should be aware too. &lt;br&gt;
F:  Django uses the F() object to generate an SQL expression that describes the required operation at the database level. &lt;br&gt;
DurationField: DurationField is a field for storing periods of time.&lt;br&gt;
Sum: is an aggregation clause &lt;a href="https://docs.djangoproject.com/en/4.0/topics/db/aggregation/" rel="noopener noreferrer"&gt;info&lt;/a&gt;.&lt;br&gt;
ExpressionWrapper: If the fields that you’re combining are of different types you’ll need to tell Django what kind of field will be returned. Since F() does not directly support output_field you will need to wrap the expression with ExpressionWrapper.&lt;br&gt;
datetime: The datetime module supplies classes for manipulating dates and times.&lt;br&gt;
time: Time access and conversions.&lt;br&gt;
timedelta: A timedelta object represents a duration, the difference between two dates or times.&lt;br&gt;
You can find more informations &lt;a href="https://docs.python.org/3/library/datetime.html" rel="noopener noreferrer"&gt;here &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can rewrite our view as this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

def home_view(request):

    day_since=timezone.now().date()-timedelta(days=7)       
    query_times = Times.objects.filter(end_time__isnull = False).filter(my_date__gte=day_since).annotate(duration=ExpressionWrapper(
                F('end_time') - F('start_time'), output_field=DurationField()))
    context= {"query_times": query_times}
    return render(request, "index.html", context)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let me explain that code. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

day_since=timezone.now().date()-timedelta(days=7) 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this row, I use timedelta to get the date of 7 days ago. So I will be able to filter only dates in that range.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

query_times = Times.objects.filter(end_time__isnull = False).filter(my_date__gte=day_since).annotate(duration=ExpressionWrapper(
                F('end_time') - F('start_time'), output_field=DurationField()))


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this I will get my records filtered with some criteria. The first is that my end_time must not be null; the second is that my date must be in the range from seven days ago to now. With annotate I create another field with the difference between end_time and start_time and this field will be called "duration" and will be a DurationField.&lt;/p&gt;

&lt;p&gt;Let's improve our index.html file. To give it some style, copy the &lt;a href="https://getbootstrap.com/docs/5.1/getting-started/introduction/" rel="noopener noreferrer"&gt;bootstrap starter template&lt;/a&gt; and paste it over index.html code. Then let's build a simple table to show our data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk36gllv6wlnddm4fjxpa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk36gllv6wlnddm4fjxpa.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then start our server and let's go to our page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5g1khz13gxa8fgs53ppe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5g1khz13gxa8fgs53ppe.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok. It works!&lt;br&gt;
So we can improve it. We can sum the duration field with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

total_time = query_times.aggregate(total_time=Sum('duration'))


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;With this we will get a dictionary. If you print the result you will get&lt;br&gt;
{'total_time': datetime.timedelta(seconds=21563)}&lt;br&gt;
So we can get our total with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sum_time=total_time.get('total_time')


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, we can get all what we need. For example, I tried to get hours and minutes without days and seconds. My sum_time could be None so I build an If statement:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

if sum_time is not None:        
     days=sum_time.days*24 
     seconds=sum_time.seconds
     hours=seconds//3600+days
     minutes=(seconds//60)%60       
else:
     days=0
     seconds=0
     hours=0
     minutes=0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And I passed them to my context:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

context= {"query_times": query_times,
                "hours": hours,
                "minutes": minutes
                }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then I added an h5 tag under the table closing tag with my new data:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;h5&amp;gt;Total time: {{ hours }} hours, {{ minutes }} minutes&amp;lt;/h5&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And this will be the final result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6e3428wziiad5vl5eri2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6e3428wziiad5vl5eri2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Congratulations! You reached the end of this very long post. &lt;br&gt;
I know that there are many ways to manage date and times with python. This was my approach for a project I was building. &lt;br&gt;
Django and Python are full of packages that help you in many ways. &lt;br&gt;
Feel free to drop your suggestions, I will appreciate.&lt;br&gt;
&lt;a href="https://github.com/r4gtl/djangoTimeAndDates" rel="noopener noreferrer"&gt;Link to github repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>programming</category>
    </item>
    <item>
      <title>How expensive it is to learn coding?</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Sun, 24 Jan 2021 12:05:51 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/how-expensive-it-is-to-learn-coding-5f81</link>
      <guid>https://forem.com/rquattrogtl/how-expensive-it-is-to-learn-coding-5f81</guid>
      <description>&lt;p&gt;Someone asks me if learning code is expensive. My answer is no. &lt;br&gt;
I think that if you are young and you are starting a specific school it may be better. In my case, I have only a light background with coding. I started only one year ago to go in deep with coding. I have only an old laptop I had recovered using Kubuntu Linux, my favourite Distro. I was scared just by the cost that could have an education in this field. The only thing I was pretty good to do was to build a pc using recycled parts of other PCs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So I tried to jump in learning to code. In the beginning, I start with a resource I think everyone use: Freecodecamp. This resource gives you some ideas about how coding works. Technicals are important, but thanks to Freecodecamp, you start to use Twitter in a different way and meet other developers. Most of them are people like you that are starting this adventure. But Twitter is full of senior developers who uses Twitter to give suggestions about everything concerning Coding World. This is a great resource you can use to learn something new every day.&lt;br&gt;
I spent some money to buy courses on Udemy, but you can find a lot of free courses searching for MOOC. English is a must-have skill, but you don’t have to let this stop you. You can find a lot of courses in your language. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Hardware Requirements&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let's talk about hardware requirements.&lt;br&gt;
As I said, I start with an old laptop. It was a good laptop with 4GB Ram, i5 processor and a 500GB HD. Not the best but it works. I gave him a new life installing Linux as OS. I used Kubuntu that was my favourite distro. &lt;br&gt;
Because of COVID, I had to give my laptop to my daughter for school to let her follow school online. So I recovered a desktop pc with the same features of the laptop. Only two weeks ago, my wife's chief gave to me two PCs that he wants to throw away because he wants to renew his office. In those PCs, I found two 250 GB SSD and 16 GB RAM. He gave me monitors too. So, I worked for two days and I upgrade my pc using the stuff I found in those PCs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;OS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Talk about the OS is hard. All of us needs different features.&lt;br&gt;
I'm a Linux User since 2012, so for me, this is the best OS I can use for coding. During the last year, I talked with a lot of Twitter friends about which Distro is the best for coding. Let's say one thing: if you want to switch from Windows to Linux, choose a user-friendly distro. If you have to waste time in the installation procedure, you will be very frustrated. I have tried a lot of distros and my Twitter friends suggested me others. A few months ago, when I switched to desktop pc, I've installed Debian 9. It's called the mother of the distros and is very good. In my experience, I think this is not for a newbie. You must have faced Linux World before using it. Two weeks ago, when I built my new "Frankenstein PC", I wanted to finish as soon as possible, so I used a Live USB I had prepared for a friend. So I installed Linux Mint 20.1 Ulyssa, the newest Linux Mint release. Now I'm trying this distro but I think it may be perfect for a Linux newbie who wants to enter in Linux world but is good also for a Linux expert. You can easily install all the tools you need to start coding.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Tools&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tools for coding are free! You can have all you need to start coding simply installing it. No more costs. I don't want to talk about useful tools here because you have so many choices that you can try them and find the best for you. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Don't be scared about how much expensive could be learning to code. This is almost free. It depends on how many courses you buy, but your commitment to study is what really matters. The Dev Community is made by people who help each other and this is what you have to do. When you learn something, write somewhere about it. It may be very useful for someone else.&lt;/p&gt;

&lt;p&gt;Thanks for reading this long post. If you have any suggestion, please feel free to comment.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>linux</category>
    </item>
    <item>
      <title>Django context processors</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Tue, 29 Dec 2020 19:19:00 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/django-context-processors-616</link>
      <guid>https://forem.com/rquattrogtl/django-context-processors-616</guid>
      <description>&lt;p&gt;In the last few months, I'm building my first project with Django. It is a project about solvents tracking and a control system of air pollution for the tannery industry. Soon I will make a series of posts in which I will explain my approach to the project. &lt;br&gt;
Now, I want to take note of a new thing I've learnt working with this project. &lt;br&gt;
First of all, I want to thanks &lt;a href="https://dev.to/gilbishkosma"&gt;Gilbish&lt;/a&gt; because I solved my problem reading his post regarding Context Processors. &lt;br&gt;
Ok, let's go.&lt;/p&gt;
&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;After building the database and a draft of the front end, I have to take the name of the company that is using my program and put it in the navbar of the base.html page, so it will be shown in every page.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftig22dqpp01ni87l92ph.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftig22dqpp01ni87l92ph.jpeg" alt="Alt Text" width="800" height="74"&gt;&lt;/a&gt;&lt;br&gt;
The Django Documentation took me to "Context Processor" subject so I tried to do some experiments. Finally, I found &lt;a href="https://dev.to/gilbishkosma/custom-context-processors-in-django-3c93"&gt;this post&lt;/a&gt; written by Gilbish and I tried to apply it to my case.&lt;/p&gt;
&lt;h3&gt;
  
  
  First Step
&lt;/h3&gt;

&lt;p&gt;First of all, in models.py I have a Model for the company's data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Company(models.Model):
    company_name = models.CharField(max_length=100)
    vat_number = models.CharField(max_length=11)
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Second Step
&lt;/h3&gt;

&lt;p&gt;In Django Documentation context processors are explained as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;context_processors is a list of dotted Python paths to callables that are used to populate the context when a template is rendered with a request. These callables take a request object as their argument and return a dict of items to be merged into the context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we can build our custom context processor that will return a dictionary with the variable we need.&lt;br&gt;
To do this, we can create a new file in our app folder, call him context_processors.py and write the function to get the data we need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from .models import Company

def get_company_name(request):

    company_name = Company.objects.all()    
    return {'company_name': company_name[0]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Third Step
&lt;/h3&gt;

&lt;p&gt;Now we have to add the path of our custom context processor to settings.py file in the Template section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
                 os.path.join(BASE_DIR, 'templates'),

                 ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',                              
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',

#path of our custom context processors
               'myapp.context_processors.get_company_name',
            ],
        },
    },
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok. Now, we can use our variable in all the templates.&lt;br&gt;
But, how can we use it?&lt;br&gt;
In my case, I put the variable in the base.html file that will be extended in other templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;a class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" href="#"&amp;gt;{{ company_name }}&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I said, this post is like a simple note for me, but I hope it can help. &lt;br&gt;
Please feel free to add comments and suggestions.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>howto</category>
    </item>
    <item>
      <title>VBA 32-bit/64-bit</title>
      <dc:creator>Stefano Ferrari</dc:creator>
      <pubDate>Mon, 31 Aug 2020 13:59:24 +0000</pubDate>
      <link>https://forem.com/rquattrogtl/vba-32-bit-64-bit-1pd3</link>
      <guid>https://forem.com/rquattrogtl/vba-32-bit-64-bit-1pd3</guid>
      <description>&lt;p&gt;In the last few years, I built a good number of applications using MSAccess and all the useful tools it has. &lt;br&gt;
Ok, the title of this post may be a little strange because sincerely, who are still using an old 32-bit version? We are in 2020! In my case, I have some small clients that have for example old warehouse machinery that they need to integrate into the management system linking them to a server. So what happens is that we can have a system with, for example, 10 pc with a 64-bit version and 1 with a 32-bit version. This is a problem especially if you have built an auto-update system. So, I searched for a solution that could help me to fix this issue. The problem for me was that the declaration statement of a function in a module is different for the 2 versions, or rather in the 64-bit version, you have to add the keyword PtrSafe to the declaration statement. Microsoft ensures that adding the PtrSafe keyword, the declaration statement will work in both versions but at some conditions. So, when I built the first version in 32-bit, I had this declaration statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Declare Function aht_apiGetOpenFileName Lib "comdlg32.dll" _
    Alias "GetOpenFileNameA" (OFN As tagOPENFILENAME) As Boolean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now I must change it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Declare PtrSafe Function aht_apiGetOpenFileName Lib "comdlg32.dll" _
    Alias "GetOpenFileNameA" (OFN As tagOPENFILENAME) As Boolean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty simple. But as Microsoft said in &lt;a href="https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/ptrsafe-keyword"&gt;this article&lt;/a&gt;, if I want to continue to use the rest of the 32-bit code, it has to respect some conditions. So I decide to use the If statement of the Microsoft Article as I haven't a large number of Functions declared in that way. This is the final result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#If VBA7 Then
Declare PtrSafe Function aht_apiGetOpenFileName Lib "comdlg32.dll" _
    Alias "GetOpenFileNameA" (OFN As tagOPENFILENAME) As Boolean

#Else

Declare Function aht_apiGetOpenFileName Lib "comdlg32.dll" _
    Alias "GetOpenFileNameA" (OFN As tagOPENFILENAME) As Boolean

#End If
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>msaccess</category>
      <category>vba</category>
      <category>functions</category>
    </item>
  </channel>
</rss>
