<?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>DEV Community: Samuel Lubliner</title>
    <description>The latest articles on DEV Community by Samuel Lubliner (@samuellubliner).</description>
    <link>https://dev.to/samuellubliner</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%2F1123029%2F51c0605e-d705-4aaf-8072-135b72416810.jpeg</url>
      <title>DEV Community: Samuel Lubliner</title>
      <link>https://dev.to/samuellubliner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samuellubliner"/>
    <language>en</language>
    <item>
      <title>SageMath Installation</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Thu, 15 Aug 2024 18:47:25 +0000</pubDate>
      <link>https://dev.to/samuellubliner/sagemath-installation-2pep</link>
      <guid>https://dev.to/samuellubliner/sagemath-installation-2pep</guid>
      <description>&lt;p&gt;&lt;a href="https://www.sagemath.org/" rel="noopener noreferrer"&gt;SageMath&lt;/a&gt; is a free open-source mathematics software system that builds on many existing open-source packages, including NumPy, SciPy, matplotlib, Sympy, Maxima, GAP, FLINT, R, and more. Unlike proprietary software like Magma, Maple, Mathematica, and MATLAB, Sage is free to use and allows you to view and modify the source code. If you're familiar with Python, you'll feel right at home with Sage as it extends Python with a robust set of mathematical tools.&lt;/p&gt;

&lt;p&gt;The easiest way to get started with Sage is by running code in a browser-based workbook on a platform called CoCalc. CoCalc's free tier offers several benefits, including collaboration, automatic dependency management, and the convenience of executing Sage code without installing the software locally. However, after using CoCalc for a while, I found myself wanting a faster setup, free from the limitations of a cloud environment. This led me to install Sage locally on my machine.&lt;/p&gt;

&lt;p&gt;If you're running Windows, installing Sage requires a few extra steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://learn.microsoft.com/en-us/windows/wsl/" rel="noopener noreferrer"&gt;Windows Subsystem for Linux&lt;/a&gt;. Make sure you are using WSL2.&lt;/li&gt;
&lt;li&gt;Reading &lt;a href="https://learn.microsoft.com/en-us/windows/wsl/setup/environment" rel="noopener noreferrer"&gt;Set up a WSL development environment&lt;/a&gt; is also helpful.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can find instructions for local installation in the &lt;a href="https://doc.sagemath.org/html/en/installation/index.html" rel="noopener noreferrer"&gt;Sage Installation Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are several ways to install Sage, each with its advantages. Installing Sage from source offers the most flexibility, but it's a lengthy process that may present some challenges. Installing the necessary dependencies can take a considerable amount of time, and the &lt;code&gt;make&lt;/code&gt; command — used to build Sage — will also require some patience, depending on your computer's resources.&lt;/p&gt;

&lt;p&gt;For those seeking a simpler and quicker installation process, using conda-forge is an excellent alternative. Conda-forge is a community-driven collection of packages for conda, making it easy to install and manage Sage without dealing with the complexities of a source build. Here's how to get started with installing sage on WSL Ubuntu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-O&lt;/span&gt; &lt;span class="s2"&gt;"https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.sh"&lt;/span&gt;
bash Miniforge3-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;-&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;.sh
conda create &lt;span class="nt"&gt;-n&lt;/span&gt; sage sage &lt;span class="nv"&gt;python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing Sage via conda, you'll see a message similar to the following. Pay attention to the instructions provided, as they guide you on how to activate and manage your new Sage environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Transaction finished

To activate this environment, use:

    micromamba activate /home/samuel-lubliner/miniforge3

Or to execute a single &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;in &lt;/span&gt;this environment, use:

    micromamba run &lt;span class="nt"&gt;-p&lt;/span&gt; /home/samuel-lubliner/miniforge3 mycommand

installation finished.
Do you wish to update your shell profile to automatically initialize conda?
This will activate conda on startup and change the &lt;span class="nb"&gt;command &lt;/span&gt;prompt when activated.
If you&lt;span class="s1"&gt;'d prefer that conda'&lt;/span&gt;s base environment not be activated on startup,
   run the following &lt;span class="nb"&gt;command &lt;/span&gt;when conda is activated:

conda config &lt;span class="nt"&gt;--set&lt;/span&gt; auto_activate_base &lt;span class="nb"&gt;false

&lt;/span&gt;You can undo this by running &lt;span class="sb"&gt;`&lt;/span&gt;conda init &lt;span class="nt"&gt;--reverse&lt;/span&gt; &lt;span class="nv"&gt;$SHELL&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;? &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;yes&lt;/span&gt;|no]
&lt;span class="o"&gt;[&lt;/span&gt;no] &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prompt asks whether you want conda to automatically initialize every time your shell starts. I prefer to keep my environment clean, so I chose no. This choice keeps the base environment inactive on startup, which helps prevent cluttering the command prompt with unnecessary environment activations. If you prefer this setup, type &lt;code&gt;no&lt;/code&gt; when prompted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;You have chosen to not have conda modify your shell scripts at all.
To activate conda&lt;span class="s1"&gt;'s base environment in your current shell session:

eval "$(/home/samuel-lubliner/miniforge3/bin/conda shell.YOUR_SHELL_NAME hook)"

To install conda'&lt;/span&gt;s shell functions &lt;span class="k"&gt;for &lt;/span&gt;easier access, first activate, &lt;span class="k"&gt;then&lt;/span&gt;:

conda init

Thank you &lt;span class="k"&gt;for &lt;/span&gt;installing Miniforge3!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Manually activating your environment ensures that you maintain control over when and how your conda environments are loaded. This approach is beneficial if you use multiple environments.&lt;/p&gt;

&lt;p&gt;Since I opted not to have conda modify my shell scripts, I run Sage manually using the following commands. This method ensures a clean environment and gives me control over when to activate Sage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;samuel_lubliner@DESKTOP-QGSGOAI:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;/home/samuel_lubliner/miniforge3/bin/conda shell.bash hook&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;base&lt;span class="o"&gt;)&lt;/span&gt; samuel_lubliner@DESKTOP-QGSGOAI:~&lt;span class="nv"&gt;$ &lt;/span&gt;conda activate sage
&lt;span class="o"&gt;(&lt;/span&gt;sage&lt;span class="o"&gt;)&lt;/span&gt; samuel_lubliner@DESKTOP-QGSGOAI:~&lt;span class="nv"&gt;$ &lt;/span&gt;sage &lt;span class="nt"&gt;-n&lt;/span&gt; jupyter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The first command initializes conda in your current shell.&lt;/li&gt;
&lt;li&gt;The second command activates the sage environment.&lt;/li&gt;
&lt;li&gt;The third command starts Sage with the Jupyter notebook interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice that (base) indicates the conda base environment is activated, and (sage) shows that the sage environment is active. Running these commands each time can become repetitive, so let's automate this process by creating a bash script. We can create the file &lt;code&gt;sage_nb.sh&lt;/code&gt;. If you are using WSL, the &lt;a href="https://doc.sagemath.org/html/en/installation/launching.html" rel="noopener noreferrer"&gt;docs&lt;/a&gt; recommend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Switch to desired windows directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /mnt/c/path/to/desired/starting/directory
&lt;span class="c"&gt;# Start the Jupyter notebook&lt;/span&gt;
SAGE_ROOT/sage &lt;span class="nt"&gt;--notebook&lt;/span&gt;
&lt;span class="c"&gt;# Alternatively you can run JupyterLab - delete the line above, and uncomment the line below&lt;/span&gt;
&lt;span class="c"&gt;#SAGE_ROOT/sage --notebook jupyterlab&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, I installed JupyterLab because I prefer its more modern interface. Here is my script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Start JupyterLab&lt;/span&gt;
/home/samuel_lubliner/miniforge3/envs/sage/bin/sage &lt;span class="nt"&gt;--notebook&lt;/span&gt; jupyterlab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the script, you first need to make it executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;ug+x ~/sage_nb.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run the script whenever you want to start Sage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
./sage_nb.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is set up correctly, running the script will start the Jupyter server in your terminal. From here, you can begin working with Sage in your browser.&lt;/p&gt;

&lt;p&gt;If you prefer a more user-friendly approach, you can take this bash script a step further by creating a clickable shortcut on your desktop. This allows you to start Sage and JupyterLab with a double-click. You can find detailed instructions on how to create this shortcut in the &lt;a href="https://doc.sagemath.org/html/en/installation/launching.html#create-a-shortcut" rel="noopener noreferrer"&gt;SageMath docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>computerscience</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Starting a new Django project with PostgresSQL and Docker</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Wed, 03 Jul 2024 15:36:37 +0000</pubDate>
      <link>https://dev.to/samuellubliner/starting-a-new-django-project-with-postgressql-and-docker-3hoj</link>
      <guid>https://dev.to/samuellubliner/starting-a-new-django-project-with-postgressql-and-docker-3hoj</guid>
      <description>&lt;h2&gt;
  
  
  Initial project setup:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;client-management
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;client-management
&lt;span class="nv"&gt;$ &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install &lt;/span&gt;django~&lt;span class="o"&gt;=&lt;/span&gt;5.0
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;django-admin startproject django_project &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py runserver 

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

&lt;/div&gt;



&lt;p&gt;Visit &lt;a href="http://127.0.0.1:8000/" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/&lt;/a&gt; to confirm the successful install and then quit the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;requirements.txt
&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Docker
&lt;/h2&gt;

&lt;p&gt;Use Docker to streamline local development with PostgreSQL&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read more about security before deployment&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/security/rootless/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/security/rootless/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installing Django , deactivate the virtual environment and set up Docker. Create a &lt;code&gt;Dockerfile&lt;/code&gt;, &lt;code&gt;docker-compose.yml&lt;/code&gt;, and &lt;code&gt;.dockerignore&lt;/code&gt; files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;.venv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;deactivate
&lt;span class="err"&gt;$&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Dockerfile docker-compose.yml .dockerignore
&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  About Docker
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker Image: a read-only template with instructions for creating a container&lt;/li&gt;
&lt;li&gt;Supported Python images: &lt;a href="https://hub.docker.com/_/python/" rel="noopener noreferrer"&gt;https://hub.docker.com/_/python/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Dockerfile&lt;/code&gt;: defines the custom image&lt;/li&gt;
&lt;li&gt;Docker container: running instance of a Docker image.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker-compose.yml&lt;/code&gt;: additional instructions for the container&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docker flow:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;create a new virtual environment and install Django&lt;/li&gt;
&lt;li&gt;create a new Django project within it&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;Dockerfile&lt;/code&gt; with custom image instructions&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;.dockerignore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;build the image&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;docker-compose.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Spin up containers with &lt;code&gt;docker-compose up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stop the container:

&lt;ul&gt;
&lt;li&gt;Press &lt;code&gt;Control + c&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;docker-compose down&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Detached mode
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;runs containers in the background. Use it for a single command line tab. Run &lt;code&gt;docker-compose up -d&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Error output won’t always be visible in detached mode. See the current output by running &lt;code&gt;docker-compose logs&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docker vs  local commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Preface traditional commands with &lt;code&gt;docker-compose exec [service]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose &lt;span class="nb"&gt;exec &lt;/span&gt;web python manage.py migrate
&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose &lt;span class="nb"&gt;exec &lt;/span&gt;web python manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Psycopg
&lt;/h2&gt;

&lt;p&gt;Psycopg is a database adapter. Start off with the binary version for quick installation. Update if the project needs performance boost. Learn more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.psycopg.org/psycopg3/docs/basic/install.html#binary-installation" rel="noopener noreferrer"&gt;https://www.psycopg.org/psycopg3/docs/basic/install.html#binary-installation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/databases/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/ref/databases/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Install Psycopg
&lt;/h3&gt;

&lt;p&gt;First stop running the Docker container by running &lt;code&gt;docker-compose down&lt;/code&gt;. Docker replaces the virtual environment. The Docker host replaces the local operating system. Since I am using docker, I won’t install locally. Instead, I will just update requirements.txt with the &lt;code&gt;psycopg[binary]&lt;/code&gt; package at the bottom of the file.&lt;/p&gt;

&lt;h2&gt;
  
  
  About &lt;code&gt;docker-compose.yml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; specifies two separate containers running within Docker.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;web for the Django local server&lt;/li&gt;
&lt;li&gt;db for the PostgreSQL database.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Docker containers are ephemeral. Information is lost when the container stops running. In &lt;code&gt;docker-compose.yml&lt;/code&gt;, the &lt;code&gt;postgres_data&lt;/code&gt; volumes mount binds to the local computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure PostgreSQL
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Configure the environment to use trust authentication for the database. For a databases with many users, be more explicit with permissions.&lt;/li&gt;
&lt;li&gt;Update the &lt;code&gt;DATABASES&lt;/code&gt; config in &lt;code&gt;django_project/settings.py&lt;/code&gt; file to use PostgreSQL&lt;/li&gt;
&lt;li&gt;Now build the new image and start the two containers in detached mode by running &lt;code&gt;docker-compose up -d --build&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Refresh the Django welcome page at &lt;a href="http://127.0.0.1:8000/" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/&lt;/a&gt; to show Django has successfully connected to PostgreSQL via Docker. Remember to &lt;code&gt;docker-compose down&lt;/code&gt; to save computer resources when you are finished.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Up next
&lt;/h2&gt;

&lt;p&gt;Before migrating, I will add a custom user model.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>docker</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Django: Generic List and Detail Views</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Sat, 01 Jun 2024 17:44:04 +0000</pubDate>
      <link>https://dev.to/samuellubliner/django-generic-list-and-detail-views-3nfc</link>
      <guid>https://dev.to/samuellubliner/django-generic-list-and-detail-views-3nfc</guid>
      <description>&lt;p&gt;From learn.firstdraft and &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Generic_views"&gt;MDN Django Generic Views&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use generic class-based list views for listing multiple records, and detail views for displaying individual records.&lt;/li&gt;
&lt;li&gt;Extract information from URL patterns and pass it to the view.&lt;/li&gt;
&lt;li&gt;These views reduce the amount of view code needed, streamlining the development process.&lt;/li&gt;
&lt;li&gt;Implement pagination in list views to efficiently handle large datasets.&lt;/li&gt;
&lt;li&gt;Apply these concepts to create pages to view our books and authors, passing data from URLs to the views.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Book List Page
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Extend the base template &lt;code&gt;base_generic.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Display a list of all available book records.&lt;/li&gt;
&lt;li&gt;URL: &lt;code&gt;catalog/books/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Each book's title is a hyperlink to the associated book detail page.&lt;/li&gt;
&lt;li&gt;Display the author for each book record.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  URL Mapping
&lt;/h2&gt;

&lt;p&gt;Set the path for &lt;code&gt;books/&lt;/code&gt; in &lt;code&gt;/catalog/urls.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;path()&lt;/code&gt; function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines a pattern to match the &lt;code&gt;/catalog/books/&lt;/code&gt; URL.&lt;/li&gt;
&lt;li&gt;Calls the view function returned by &lt;code&gt;views.BookListView.as_view()&lt;/code&gt; if the URL matches.&lt;/li&gt;
&lt;li&gt;Provides a name for this particular URL mapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The view function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is implemented as a class, &lt;code&gt;BookListView&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Inherits from Django's generic class-based views.&lt;/li&gt;
&lt;li&gt;Is converted to a view function using the &lt;code&gt;as_view()&lt;/code&gt; method.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  View (class-based)
&lt;/h2&gt;

&lt;p&gt;Instead of writing the book list view as a regular function-based view (similar to a Rails controller action):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queries the database for all books.&lt;/li&gt;
&lt;li&gt;Calls &lt;code&gt;render()&lt;/code&gt; to pass the list to a specified template.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using a class-based generic list view (ListView) is preferable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inherits from an existing view.&lt;/li&gt;
&lt;li&gt;The generic view already implements most of the functionality.&lt;/li&gt;
&lt;li&gt;Aligns with Django best practices for a more robust list view with less code, repetition, and maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;catalog/views.py&lt;/code&gt;, the generic view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queries the database.&lt;/li&gt;
&lt;li&gt;Renders a template.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The template can access the list of books using a template variable. By default, generic views look for templates in the &lt;code&gt;/application_name/templates/application_name/the_model_name_list.html&lt;/code&gt; path.&lt;/p&gt;

&lt;p&gt;To modify the default behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specify a different template file if you need to use multiple views for the same model.&lt;/li&gt;
&lt;li&gt;Use a different template variable name if needed.&lt;/li&gt;
&lt;li&gt;Customize the queryset to filter or change the subset of results returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overriding methods in class-based views
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It is possible to override some of the class methods, offering more flexibility than just setting the queryset attribute.&lt;/li&gt;
&lt;li&gt;For instance, override &lt;code&gt;get_context_data()&lt;/code&gt; to pass additional context variables to the template.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the existing context from the superclass.&lt;/li&gt;
&lt;li&gt;Add new context information.&lt;/li&gt;
&lt;li&gt;Return the new context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See &lt;a href="https://docs.djangoproject.com/en/5.0/topics/class-based-views/generic-display/"&gt;Built-in class-based generic views Django docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the List View Template
&lt;/h2&gt;

&lt;p&gt;The generic class-based list view for a Book model in a catalog application expects the template file to be located at &lt;code&gt;/django-locallibrary-tutorial/catalog/templates/catalog/book_list.html&lt;/code&gt;. This template should extend the base template.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditional execution
&lt;/h2&gt;

&lt;p&gt;Template tags check whether &lt;code&gt;book_list&lt;/code&gt; has been defined and is not empty.&lt;/p&gt;

&lt;p&gt;For more information about conditional operators, see: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/templates/builtins/#if"&gt;Django Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  For loops
&lt;/h2&gt;

&lt;p&gt;The template uses template tags to loop and populate the book template variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing variables
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Access the fields using dot notation: &lt;code&gt;book.field_name&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Call functions in the model from within template
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Book.get_absolute_url()&lt;/code&gt; gets a URL to display the associated detail record.&lt;/li&gt;
&lt;li&gt;Note: There is no way to pass arguments.&lt;/li&gt;
&lt;li&gt;Warning: Be aware of side effects when calling functions in templates. Be sure not to accidentally do something destructive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Update the Base Template
&lt;/h2&gt;

&lt;p&gt;To enable the link on all pages, update &lt;code&gt;/django-locallibrary-tutorial/catalog/templates/base_generic.html&lt;/code&gt; to use &lt;code&gt;{% url 'books' %}&lt;/code&gt;. The URL mapping for the book detail pages is needed to create hyperlinks to individual books.&lt;/p&gt;

&lt;h2&gt;
  
  
  Book detail page
&lt;/h2&gt;

&lt;p&gt;The book detail page displays information accessed using the URL &lt;code&gt;catalog/book/&amp;lt;id&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL Mapping
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;/catalog/urls.py&lt;/code&gt;, the 'book-detail' path function defines a URL pattern, associates it with a generic class-based detail view, and assigns it a name. The &lt;code&gt;&amp;lt;int:pk&amp;gt;&lt;/code&gt; part captures the book ID, where &lt;code&gt;pk&lt;/code&gt; stands for primary key, uniquely identifying the book in the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing additional options in your URL maps
&lt;/h2&gt;

&lt;p&gt;You may pass a dictionary containing additional options to the view.&lt;/p&gt;

&lt;h2&gt;
  
  
  View (class-based)
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;catalog/views.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DetailView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create the template at &lt;code&gt;/django-locallibrary-tutorial/catalog/templates/catalog/book_detail.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The view will pass the Book record's information to the template.&lt;/li&gt;
&lt;li&gt;Access the book's details in the template using the variable named &lt;code&gt;object&lt;/code&gt; or &lt;code&gt;book&lt;/code&gt; (the model's name).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If the record doesn't exist ...
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Generic class-based detail view raises an exception&lt;/li&gt;
&lt;li&gt;Http404&lt;/li&gt;
&lt;li&gt;Resource not found&lt;/li&gt;
&lt;li&gt;This behavior can be customized&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the Detail View Template
&lt;/h2&gt;

&lt;p&gt;For a Book model in an catalog application, the generic class-based detail view expects the template file to be located at &lt;code&gt;/django-locallibrary-tutorial/catalog/templates/catalog/book_detail.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To create this template:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;url&lt;/code&gt; template tag can reverse the 'author-detail' URL and pass it the author instance for the book. Using &lt;code&gt;get_absolute_url()&lt;/code&gt; is preferred because any necessary changes need to be made only in the author model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The template should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extend the base template&lt;/li&gt;
&lt;li&gt;Override the content block.&lt;/li&gt;
&lt;li&gt;Use conditional processing and for loops to iterate through lists of objects.&lt;/li&gt;
&lt;li&gt;Access the context fields using dot notation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Retrieve the set of &lt;code&gt;BookInstance&lt;/code&gt; records associated with a particular Book, with the &lt;code&gt;book.bookinstance_set.all()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Django constructs the function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;by lower-casing the ForeignKey model&lt;/li&gt;
&lt;li&gt;followed by &lt;code&gt;_set&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;all()&lt;/code&gt; to get all records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You cannot use the &lt;code&gt;filter()&lt;/code&gt; method directly in templates because you cannot specify arguments to functions.&lt;/p&gt;

&lt;p&gt;If you don't define an order (on your class-based view or model), there will be errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;date-time] &lt;span class="s2"&gt;"GET /catalog/books/?page=1 HTTP/1.1"&lt;/span&gt; 200 1637
/foo/local_library/venv/lib/python3.5/site-packages/django/views/generic/list.py:99: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: &amp;lt;QuerySet &lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;Author: Lubiner, Samuel&amp;gt;, &amp;lt;Author: Van Rossum, Guido&amp;gt;, &amp;lt;Author: Torvalds, Linus&amp;gt;]&amp;gt;
  &lt;span class="nv"&gt;allow_empty_first_page&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;allow_empty_first_page, &lt;span class="k"&gt;**&lt;/span&gt;kwargs&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The paginator object expects an &lt;code&gt;ORDER BY&lt;/code&gt; clause executed on your underlying database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pagination
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Django has built-in support for pagination&lt;/li&gt;
&lt;li&gt;Incorporated into the generic class-based list views&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Templates
&lt;/h2&gt;

&lt;p&gt;With paginated data, add support to the template to scroll through the results set. To paginate all list views, add this to the base template. The &lt;code&gt;page_obj&lt;/code&gt; gets all the information about the current page, previous pages, page numbers, etc.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{{ request.path }}&lt;/code&gt; gets the current page URL for creating the pagination links, independent of the object that we're paginating.&lt;/p&gt;

&lt;h2&gt;
  
  
  Book List Page
&lt;/h2&gt;

&lt;p&gt;Create the author detail and list views.&lt;/p&gt;

&lt;p&gt;Author list: &lt;code&gt;catalog/authors/&lt;/code&gt;&lt;br&gt;
Detail view for the author with a primary key field: &lt;code&gt;catalog/author/&amp;lt;id&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After creating the URL mapper for the author list page, update the "All authors" link in the base template.&lt;/li&gt;
&lt;li&gt;After creating the URL mapper for the author detail page, update the book detail view template so the author link points to the new author detail page.&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;get_absolute_url()&lt;/code&gt; on the author model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  See also
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/class-based-views/generic-display/"&gt;Built-in class-based generic views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/class-based-views/generic-display/"&gt;Generic display views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/class-based-views/intro/"&gt;Introduction to class-based views&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/templates/builtins/"&gt;Built-in template tags and filters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/pagination/"&gt;Pagination&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/db/queries/#related-objects"&gt;Making queries &amp;gt; Related objects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Django: Homepage</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Thu, 30 May 2024 16:37:05 +0000</pubDate>
      <link>https://dev.to/samuellubliner/django-homepage-3lnh</link>
      <guid>https://dev.to/samuellubliner/django-homepage-3lnh</guid>
      <description>&lt;p&gt;from: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Home_page"&gt;https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Home_page&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data flow and handling HTTP requests and responses
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;URL mappers direct URLs and information to view functions&lt;/li&gt;
&lt;li&gt;View functions retrieve data from models and render HTML&lt;/li&gt;
&lt;li&gt;Templates: Define HTML for displaying data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the index page
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;catalog/&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index page&lt;/li&gt;
&lt;li&gt;includes counts of records in the database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  URL mapping
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;locallibrary/urls.py&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processes URLs starting with &lt;code&gt;catalog/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;catalog.urls&lt;/code&gt; processes the substring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The import function &lt;code&gt;django.urls.include()&lt;/code&gt; splits the URL string and sends the substring to the URLconf module.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/catalog/urls.py&lt;/code&gt; is a placeholder for the URLConf module&lt;/p&gt;

&lt;p&gt;&lt;code&gt;path()&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines a URL pattern and associates it with a view function.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;name&lt;/code&gt; parameter is a unique identifier for URL mapping.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;name&lt;/code&gt; parameter to reverse the URL mapper and dynamically generate a URL that directs to a resource.&lt;/li&gt;
&lt;li&gt;Reversed URL mapping is more robust than hard-coded links.&lt;/li&gt;
&lt;li&gt;Use the name parameter to create links&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  View
&lt;/h2&gt;

&lt;p&gt;A view function&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles an HTTP request&lt;/li&gt;
&lt;li&gt;Retrieves necessary data from the database&lt;/li&gt;
&lt;li&gt;Generates an HTML page using a template to display the data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first line in &lt;code&gt;catalog/views.py&lt;/code&gt; imports &lt;code&gt;render()&lt;/code&gt; to generate an HTML file.&lt;/p&gt;

&lt;p&gt;The next line imports the model classes used to access data in views.&lt;/p&gt;

&lt;p&gt;The view function 'index'&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetches the number of records using &lt;code&gt;objects.all()&lt;/code&gt; on the model classes.&lt;/li&gt;
&lt;li&gt;Retrieves a collection of &lt;code&gt;BookInstance&lt;/code&gt; objects where the status field is set to 'a' for available&lt;/li&gt;
&lt;li&gt;Calls the &lt;code&gt;render()&lt;/code&gt; function to create an HTML page a return the page as a response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;context&lt;/code&gt; variable is a dictionary, containing the placeholder data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Template
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A template defines the structure a file, such as an HTML page&lt;/li&gt;
&lt;li&gt;Use placeholders for content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the index view from 'locallibrary/catalog/views.py', the &lt;code&gt;render()&lt;/code&gt; function will expect to find &lt;code&gt;/django-locallibrary-tutorial/catalog/templates/index.html&lt;/code&gt; or return an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending templates
&lt;/h2&gt;

&lt;p&gt;Declare a base template and extend it to replace different parts for each specific page.&lt;/p&gt;

&lt;p&gt;Template tags&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;loop through lists&lt;/li&gt;
&lt;li&gt;conditional operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Template syntax&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reference variables from the view&lt;/li&gt;
&lt;li&gt;Use filters to format variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When defining a template specify the base template using the extends template tag. Then declare sections from the template to be replaced.&lt;/p&gt;

&lt;p&gt;Our base template is &lt;code&gt;/django-locallibrary-tutorial/catalog/templates/base_generic.html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The base template references &lt;code&gt;/django-locallibrary-tutorial/catalog/static/css/styles.css&lt;/code&gt; that provides additional styling.&lt;/p&gt;

&lt;h2&gt;
  
  
  The index template
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;/django-locallibrary-tutorial/catalog/templates/index.html&lt;/code&gt; starts by extending the base template and then customizes the default content block specific to the template's needs.&lt;/p&gt;

&lt;p&gt;Template variables&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Placeholders for the information from the view&lt;/li&gt;
&lt;li&gt;Variables are enclosed with double brace handlebars&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The names of the variables correspond to the keys provided in the context dictionary within the view's &lt;code&gt;render()&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencing static files in templates
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/howto/static-files/"&gt;https://docs.djangoproject.com/en/5.0/howto/static-files/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Static resources include JavaScript, CSS, and images. You can specify the location in your templates relative to the &lt;code&gt;STATIC_URL&lt;/code&gt; global setting. The default value of &lt;code&gt;STATIC_URL&lt;/code&gt; is set to &lt;code&gt;'/static/'&lt;/code&gt;. You can change it and host resources on a content delivery network.&lt;/p&gt;

&lt;p&gt;To reference static files in a template, initially load the static template tag to include the template library. After that, use the static tag to provide the relative path to the desired file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linking to URLs
&lt;/h2&gt;

&lt;p&gt;The base template uses the url template tag.&lt;/p&gt;

&lt;p&gt;This tag&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes the name of a &lt;code&gt;path()&lt;/code&gt; function called in &lt;code&gt;urls.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Accepts the values for arguments the associated view will receive&lt;/li&gt;
&lt;li&gt;Returns a URL used to link to the resource&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configuring where to find the templates
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/templates/"&gt;https://docs.djangoproject.com/en/5.0/topics/templates/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Django searches for templates specified in the &lt;code&gt;TEMPLATES&lt;/code&gt; object in the settings&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;settings.py&lt;/code&gt; &lt;code&gt;'APP_DIRS': True&lt;/code&gt; instructs Django to look for templates within a "templates" subdirectory inside each app of the project. You can also specify particular directories for Django to search by setting &lt;code&gt;'DIRS': []&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  View my commits here:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Samuel-Lubliner/local-library-django-tutorial/commit/3727b04dd95abbdf4e6d974fb0da10e17b16176c"&gt;https://github.com/Samuel-Lubliner/local-library-django-tutorial/commit/3727b04dd95abbdf4e6d974fb0da10e17b16176c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/intro/tutorial03/"&gt;Writing your first Django app, part 3: Views and Templates&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/topics/http/urls/"&gt;URL dispatcher&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/topics/http/views/"&gt;View functions&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/topics/templates/"&gt;Templates&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/howto/static-files/"&gt;Managing static files&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/topics/http/shortcuts/#django.shortcuts.render"&gt;Django shortcut functions&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>Django: Admin</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Tue, 28 May 2024 20:26:53 +0000</pubDate>
      <link>https://dev.to/samuellubliner/django-admin-2f3i</link>
      <guid>https://dev.to/samuellubliner/django-admin-2f3i</guid>
      <description>&lt;p&gt;From: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Admin_site"&gt;https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Admin_site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See my &lt;code&gt;locallibrary/catalog/admin.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Samuel-Lubliner/local-library-django-tutorial/blob/main/locallibrary/catalog/admin.py"&gt;https://github.com/Samuel-Lubliner/local-library-django-tutorial/blob/main/locallibrary/catalog/admin.py&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Django admin application
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Allows creating, viewing, updating, and deleting records using models.&lt;/li&gt;
&lt;li&gt;Simplifies testing models and data during development.&lt;/li&gt;
&lt;li&gt;Useful for managing data in production environments.&lt;/li&gt;
&lt;li&gt;Recommended only for internal data management.&lt;/li&gt;
&lt;li&gt;Dependencies needed: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/"&gt;Django Admin Documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Register models to add them to the admin interface.&lt;/li&gt;
&lt;li&gt;Configure the admin area for better display.&lt;/li&gt;
&lt;li&gt;Create a new "superuser."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Registering models
&lt;/h2&gt;

&lt;p&gt;Register models in &lt;code&gt;/django-locallibrary-tutorial/catalog/admin.py&lt;/code&gt;. This is the simplest way of registering models with the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a superuser
&lt;/h2&gt;

&lt;p&gt;A superuser account has full access to the site and all needed permissions using &lt;code&gt;manage.py&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log into the admin site with a user account that has Staff status enabled.&lt;/li&gt;
&lt;li&gt;View and create records with permissions to manage all objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the same directory as &lt;code&gt;manage.py&lt;/code&gt; run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 manage.py createsuperuser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restart the development server to test the login:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 manage.py runserver&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging in and using the site
&lt;/h2&gt;

&lt;p&gt;Open the /admin URL and enter the superuser credentials. The GUI allows you to view models and edit field values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced configuration
&lt;/h2&gt;

&lt;p&gt;List views and detail views provide greater customization&lt;/p&gt;

&lt;p&gt;Find a reference of the admin site in the docs: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Register a ModelAdmin class
&lt;/h2&gt;

&lt;p&gt;Comment out the original registrations. Then Define a &lt;code&gt;ModelAdmin&lt;/code&gt; class and register it with the model. See: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#modeladmin-objects"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#modeladmin-objects&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure list views
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;list_display&lt;/code&gt; to add additional fields to the view. See more at &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add list filters
&lt;/h2&gt;

&lt;p&gt;To filter displayed items, list fields in the &lt;code&gt;list_filter&lt;/code&gt; attribute.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sectioning the detail view
&lt;/h2&gt;

&lt;p&gt;To add sections, refer to: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inline editing of associated records
&lt;/h2&gt;

&lt;p&gt;For inline editing of associated records, refer to: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.inlines"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.inlines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Declaring inlines&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;TabularInline&lt;/code&gt; (horizontal layout) &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.TabularInline"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.TabularInline&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;StackedInline&lt;/code&gt; (vertical layout, default) &lt;a href="https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.StackedInline"&gt;https://docs.djangoproject.com/en/5.0/ref/contrib/admin/#django.contrib.admin.StackedInline&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Django: Sample data</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Tue, 28 May 2024 00:28:10 +0000</pubDate>
      <link>https://dev.to/samuellubliner/django-sample-data-ng2</link>
      <guid>https://dev.to/samuellubliner/django-sample-data-ng2</guid>
      <description>&lt;h2&gt;
  
  
  Sample Data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Is helpful when developing&lt;/li&gt;
&lt;li&gt;Sample data scripts expose issues with data models&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Querying in the shell
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;locallibrary
python3 manage.py shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interactive Python environment can be used to create records and query the database.&lt;/p&gt;

&lt;p&gt;Import all necessary modules and models for the session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;from catalog.models import Book
Book.objects.all&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;QuerySet &lt;span class="o"&gt;[]&amp;gt;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An empty query set was returned.&lt;/p&gt;

&lt;p&gt;Add a book:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;book &lt;span class="o"&gt;=&lt;/span&gt; Book&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Python Tutorial"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
book.save&lt;span class="o"&gt;()&lt;/span&gt;
Book.objects.all&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;QuerySet &lt;span class="o"&gt;[&lt;/span&gt;&amp;lt;Book: Python Tutorial&amp;gt;]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A book was successfully created. Importing everything in the beginning of the shell is painful.&lt;/p&gt;

&lt;p&gt;Exit the the shell with &lt;code&gt;exit()&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying with shell_plus
&lt;/h2&gt;

&lt;p&gt;Navigate to the same directory as &lt;code&gt;requirements.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shell_plus&lt;/code&gt; doesn’t come with Django out-of-the-box.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;django-extensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the new package to the list of installed packages.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;pip freeze&lt;/code&gt; from the same directory as &lt;code&gt;requirements.txt&lt;/code&gt; to update the file. Otherwise, you will create another &lt;code&gt;requirements.txt&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to &lt;code&gt;settings.py&lt;/code&gt; and register the extension in &lt;code&gt;INSTALLED_APPS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, navigate to the &lt;code&gt;locallibrary&lt;/code&gt; directory where &lt;code&gt;manage.py&lt;/code&gt; is located and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 manage.py shell_plus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can query without needing to import models manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample data script
&lt;/h2&gt;

&lt;p&gt;Install the Faker library and add it to &lt;code&gt;requirements.txt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;Faker
pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;code&gt;create_sample_data.py&lt;/code&gt; at &lt;a href="https://github.com/Samuel-Lubliner/local-library-django-tutorial/blob/main/locallibrary/create_sample_data.py"&gt;https://github.com/Samuel-Lubliner/local-library-django-tutorial/blob/main/locallibrary/create_sample_data.py&lt;/a&gt;&lt;br&gt;
Run the sample data script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 create_sample_data.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start querying run &lt;code&gt;python3 manage.py shell_plus&lt;/code&gt; &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Django: Using models</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Mon, 27 May 2024 03:53:10 +0000</pubDate>
      <link>https://dev.to/samuellubliner/django-using-models-54bh</link>
      <guid>https://dev.to/samuellubliner/django-using-models-54bh</guid>
      <description>&lt;p&gt;From: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Models"&gt;MDN Web Docs&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Python objects&lt;/li&gt;
&lt;li&gt;Define the data structure&lt;/li&gt;
&lt;li&gt;Independent from the database schema&lt;/li&gt;
&lt;li&gt;Facilitate communication between Django and the database via Object-Relational Mapper&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Designing Models
&lt;/h2&gt;

&lt;p&gt;Create separate models for every object. Models can also be used to represent selection-list options.&lt;/p&gt;

&lt;p&gt;Consider the relationships between objects. Relationships include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one to one (OneToOneField)&lt;/li&gt;
&lt;li&gt;one to many (ForeignKey)&lt;/li&gt;
&lt;li&gt;many to many (ManyToManyField)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multiplicities define the maximum and minimum number of each model that may be present in the relationship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model definition
&lt;/h2&gt;

&lt;p&gt;Models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defined in &lt;code&gt;models.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Extend &lt;code&gt;django.db.models.Model&lt;/code&gt; class&lt;/li&gt;
&lt;li&gt;Can include fields, methods and metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fields
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fields in a model represent columns in a database table.&lt;/li&gt;
&lt;li&gt;Each record (row) in the table contains values for these fields.&lt;/li&gt;
&lt;li&gt;Field types are designated using specific classes that define the type of data stored.&lt;/li&gt;
&lt;li&gt;Field types can also be used for HTML form validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Field Arguments
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/models/fields/#field-options"&gt;https://docs.djangoproject.com/en/5.0/ref/models/fields/#field-options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;help_text&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;verbose_name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;default&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;null&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blank&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unique&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;primary_key&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  COMMON FIELD TYPES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/models/fields/#field-types"&gt;https://docs.djangoproject.com/en/5.0/ref/models/fields/#field-types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CharField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TextField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IntegerField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;other fields for different types of numbers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DateField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EmailField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FileField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ImageField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AutoField&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ForeignKey&lt;/code&gt; specifies one-to-many relationship to another database model&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ManyToManyField&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Metadata
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/models/options/"&gt;https://docs.djangoproject.com/en/5.0/ref/models/options/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Declare model-level metadata with &lt;code&gt;class Meta&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Useful for controlling the ordering of records returned by queries&lt;/li&gt;
&lt;li&gt;Other metadata options control the database used for the model and how the data is stored&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Methods
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;__str__()&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Python class method&lt;/li&gt;
&lt;li&gt;Provides a readable string representation of the object&lt;/li&gt;
&lt;li&gt;The string represents individual records&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;get_absolute_url()&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generates a URL to view individual records of the model&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Model management
&lt;/h2&gt;

&lt;p&gt;Use model classes to create, update, or delete records, and to run queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating and modifying records
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a record by instantiating the model and using the model's constructor.&lt;/li&gt;
&lt;li&gt;Then call &lt;code&gt;save()&lt;/code&gt; to save the object to the database.&lt;/li&gt;
&lt;li&gt;Access fields in the record using dot notation.&lt;/li&gt;
&lt;li&gt;Search for records using the model's objects attribute&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The full list of lookups:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/models/querysets/#field-lookups"&gt;https://docs.djangoproject.com/en/5.0/ref/models/querysets/#field-lookups&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making queries:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/db/queries/"&gt;https://docs.djangoproject.com/en/5.0/topics/db/queries/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Constraints
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/models/constraints/"&gt;https://docs.djangoproject.com/en/5.0/ref/models/constraints/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the LocalLibrary Models
&lt;/h2&gt;

&lt;p&gt;At the top of &lt;code&gt;/django-locallibrary-tutorial/catalog/models.py&lt;/code&gt;, the boilerplate imports the &lt;code&gt;models&lt;/code&gt; module, which provides the &lt;code&gt;models.Model&lt;/code&gt; base class that our models inherit from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Genre model
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Stores information about the book genre&lt;/li&gt;
&lt;li&gt;A single &lt;code&gt;CharField&lt;/code&gt; field is used to describe the genre&lt;/li&gt;
&lt;li&gt;Limited to 200 characters &lt;/li&gt;
&lt;li&gt;Has some &lt;code&gt;help_text&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set to&lt;code&gt;unique=True&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;One record for each genre&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;a __str__()&lt;/code&gt; method returns the name of the genre&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_absolute_url()&lt;/code&gt; method used to access a detail record &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Book model
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Represents all the general information about an available book&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CharField&lt;/code&gt; is used for the book's title and isbn.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unique&lt;/code&gt; as &lt;code&gt;true&lt;/code&gt; ensures all books have a unique ISBN&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt; is not set to be unique, because it is possible for different books to have the same name.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TextField&lt;/code&gt; for longer summary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ManyToManyField&lt;/code&gt; a book can have multiple genres and a genre can have many books&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In both field types:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The first unnamed parameter should specify the related model class

&lt;ul&gt;
&lt;li&gt;either directly by the model class&lt;/li&gt;
&lt;li&gt;or as a string with the name of the related model&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If the associated class is not yet defined, use the model's name as a string in this file&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;null=True&lt;/code&gt; permits the database to store &lt;code&gt;Null&lt;/code&gt; if no author is selected&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;on_delete=models.RESTRICT&lt;/code&gt; prevents the deletion of the book's author if it is referenced by any book&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Warning:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The default behavior is &lt;code&gt;on_delete=models.CASCADE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This means that if the author is deleted, the book would also be deleted&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;RESTRICT&lt;/code&gt; or &lt;code&gt;PROTECT&lt;/code&gt; to avoid the author being deleted while it is referenced by any book&lt;/li&gt;
&lt;li&gt;Alternatively, use &lt;code&gt;SET_NULL&lt;/code&gt; to set the book's author to &lt;code&gt;Null&lt;/code&gt; if the author record is deleted&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;__str__()&lt;/code&gt; method represents a Book record by its title field&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;get_absolute_url()&lt;/code&gt; method provides a URL to access a detailed record&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  BookInstance model
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Represents a specific copy of a book&lt;/li&gt;
&lt;li&gt;Includes information about whether the copy is available&lt;/li&gt;
&lt;li&gt;The date expected back&lt;/li&gt;
&lt;li&gt;version details&lt;/li&gt;
&lt;li&gt;unique id for the book in the library&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ForeignKey&lt;/code&gt; identifies the associated Book

&lt;ul&gt;
&lt;li&gt;each book can have many copies&lt;/li&gt;
&lt;li&gt;a copy can only have one Book&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on_delete=models.RESTRICT&lt;/code&gt; ensures the Book cannot be deleted while referenced by a &lt;code&gt;BookInstance&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CharField&lt;/code&gt; represents the specific release&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UUIDField&lt;/code&gt; for the id field to set it as the &lt;code&gt;primary_key&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;This allocates a globally unique value for each instance &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DateField&lt;/code&gt; for the &lt;code&gt;due_back&lt;/code&gt; date&lt;/li&gt;
&lt;li&gt;status &lt;code&gt;CharField&lt;/code&gt; defines a choice/selection list&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&lt;strong&gt;str&lt;/strong&gt;()&lt;/code&gt; uses a combination of its unique id and title&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Re-run the database migrations
&lt;/h2&gt;

&lt;p&gt;After models have now been created, re-run database migrations to add them to the database.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Django: Creating a skeleton website</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Thu, 23 May 2024 17:47:22 +0000</pubDate>
      <link>https://dev.to/samuellubliner/creating-a-skeleton-website-django-dg7</link>
      <guid>https://dev.to/samuellubliner/creating-a-skeleton-website-django-dg7</guid>
      <description>&lt;p&gt;From: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/skeleton_website"&gt;MDN Web Docs&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Open the terminal in a virtual or development environment&lt;/li&gt;
&lt;li&gt;Navigate to the project folder&lt;/li&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;django-admin startproject locallibrary

&lt;span class="nb"&gt;cd &lt;/span&gt;locallibrary&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;django-admin&lt;/code&gt; generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a project folder&lt;/li&gt;
&lt;li&gt;the file templates&lt;/li&gt;
&lt;li&gt;&lt;code&gt;manage.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;locallibrary&lt;/code&gt; sub-folder with the same name as the project folder. This is the entry point for the website.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sub-folder entry point contains:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;__init__.py&lt;/code&gt;: Indicates the directory is a Python package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;settings.py&lt;/code&gt;: Website settings&lt;/p&gt;

&lt;p&gt;&lt;code&gt;urls.py&lt;/code&gt;: URL-to-view mappings&lt;/p&gt;

&lt;p&gt;&lt;code&gt;wsgi.py&lt;/code&gt;: Web Server Gateway Interface for synchronous apps&lt;/p&gt;

&lt;p&gt;&lt;code&gt;asgi.py&lt;/code&gt;: Asynchronous Server Gateway Interface&lt;/p&gt;

&lt;p&gt;&lt;code&gt;manage.py&lt;/code&gt;: Project management script that creates one or more applications.&lt;/p&gt;

&lt;p&gt;Applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate, reusable components of a website&lt;/li&gt;
&lt;li&gt;Register the new applications&lt;/li&gt;
&lt;li&gt;url/path mapper for each application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the catalog application
&lt;/h2&gt;

&lt;p&gt;Run this command from the same folder as &lt;code&gt;manage.py&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 manage.py startapp catalog&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates the following folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;catalog/
        admin.py
        apps.py
        models.py
        tests.py
        views.py
        __init__.py
        migrations/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;migrations&lt;/code&gt; folder updates the database when models are modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Note for codespace development:
&lt;/h2&gt;

&lt;p&gt;Add &lt;code&gt;*&lt;/code&gt; wildcard to &lt;code&gt;ALLOWED_HOSTS&lt;/code&gt; in &lt;code&gt;settings.py&lt;/code&gt;. This allows the host to run the live preview.&lt;/p&gt;

&lt;h2&gt;
  
  
  Register the catalog application
&lt;/h2&gt;

&lt;p&gt;Add applications to &lt;code&gt;INSTALLED_APPS&lt;/code&gt; in the project settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specifying the database
&lt;/h2&gt;

&lt;p&gt;SQLite is the default database. It is suitable if you don't a lot of concurrent access. Postgres requires additional setup and is more suitable for larger sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other settings
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;TIME_ZONE&lt;/code&gt; can be configured.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SECRET_KEY&lt;/code&gt; can be changed to read from an environment variable in production.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DEBUG&lt;/code&gt; logs errors in a file instead of HTTP status code responses. Set to &lt;code&gt;False&lt;/code&gt; in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hook up the URL mapper
&lt;/h2&gt;

&lt;p&gt;While &lt;code&gt;urls.py&lt;/code&gt; can handle all the URL mappings, it's more common to route these mappings to the corresponding application.&lt;/p&gt;

&lt;p&gt;The URL mappings are managed through the &lt;code&gt;urlpatterns&lt;/code&gt; variable, which is a list of &lt;code&gt;path()&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;path()&lt;/code&gt; forwards requests to the module with the relative URL.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RedirectView&lt;/code&gt; redirects the root URL of the site.&lt;/p&gt;

&lt;p&gt;Django does not serve static files by default. Serving CSS, JavaScript, and images can be useful for the development web server. Do not do this in production.&lt;/p&gt;

&lt;p&gt;In the catalog folder, create &lt;code&gt;urls.py&lt;/code&gt; and define the imported &lt;code&gt;urlpatterns&lt;/code&gt;. Add patterns here as the application grows.&lt;/p&gt;

&lt;p&gt;Before doing this, first run a database migration to update the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running database migrations
&lt;/h2&gt;

&lt;p&gt;Django uses an Object-Relational-Mapper. Django tracks the changes to model definitions and can create database migration scripts.&lt;/p&gt;

&lt;p&gt;In the directory that contains &lt;code&gt;manage.py&lt;/code&gt;, run&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python3 manage.py makemigrations&lt;/code&gt;&lt;br&gt;
&lt;code&gt;python3 manage.py migrate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;makemigrations&lt;/code&gt; creates the migrations.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;migrate&lt;/code&gt; applies the migrations to the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the website
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;python3 manage.py runserver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Runs the development web server.&lt;/p&gt;

&lt;p&gt;An error page is expected if there are no pages/urls defined in the the root of the site.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Django (Python) Introduction</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Sun, 19 May 2024 16:51:54 +0000</pubDate>
      <link>https://dev.to/samuellubliner/django-python-introduction-i42</link>
      <guid>https://dev.to/samuellubliner/django-python-introduction-i42</guid>
      <description>&lt;p&gt;From: &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Introduction"&gt;https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Introduction&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About Django
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;High-level web framework&lt;/li&gt;
&lt;li&gt;Rapid development&lt;/li&gt;
&lt;li&gt;Secure&lt;/li&gt;
&lt;li&gt;Maintainable&lt;/li&gt;
&lt;li&gt;Scalable&lt;/li&gt;
&lt;li&gt;Free and open source&lt;/li&gt;
&lt;li&gt;Batteries included&lt;/li&gt;
&lt;li&gt;Somewhat opinionated&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Model View Template
&lt;/h2&gt;

&lt;p&gt;Django uses the Model View Template (MVT) architecture, similar to the Model View Controller architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL mapper
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;User requests go to &lt;code&gt;urls.py&lt;/code&gt;, which maps the request to a view.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  View
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The request handler function in &lt;code&gt;views.py&lt;/code&gt; processes the request and may interact with models.&lt;/li&gt;
&lt;li&gt;Django views are similar to controllers and actions in Rails.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Python objects that model data&lt;/li&gt;
&lt;li&gt;Provides an API to interact with the database&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Templates
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Define the structure of any type of file&lt;/li&gt;
&lt;li&gt;Placeholders populated with data from a model&lt;/li&gt;
&lt;li&gt;Renders HTML and other file types&lt;/li&gt;
&lt;li&gt;The rendered template is sent back as the response to the user.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Docker</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Wed, 15 May 2024 05:41:56 +0000</pubDate>
      <link>https://dev.to/samuellubliner/docker-cn9</link>
      <guid>https://dev.to/samuellubliner/docker-cn9</guid>
      <description>&lt;h2&gt;
  
  
  Why Docker?
&lt;/h2&gt;

&lt;p&gt;When collaborating on a repository shared by multiple people, Docker enables the team to share a consistent development environment. This ensures that everything runs the same and predictably across all machines. Additionally, Docker can help save resources on CodeSpaces and allows for offline development. VS Code Dev Containers offer a local alternative to GitHub CodeSpaces, providing a seamless development experience.&lt;/p&gt;

&lt;p&gt;I recently acquired a Lenovo laptop with Windows. The hardware is an upgrade from my 2013 MacBook Pro, although my MacBook is more portable. With Docker and Windows Subsystem for Linux (WSL), I can work on the same code reliably across different machines, enjoying a Linux environment on Windows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It's crucial to create your repositories within WSL rather than on the Windows file system. This improves performance and resolves some bugs. For instance, I discovered that live reloading became possible after storing files in WSL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You know you're in Windows if the terminal looks like:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PS C:&lt;span class="se"&gt;\U&lt;/span&gt;sers&lt;span class="se"&gt;\u&lt;/span&gt;ser-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Open the terminal and run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wsl &lt;span class="nt"&gt;--distribution&lt;/span&gt; Ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Next, your terminal may look something like:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name@DESKTOP:/mnt/c/Users/name&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Be careful, you are still in the Windows file system. Run &lt;code&gt;cd&lt;/code&gt; to get back to the home directory. You should see:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name@DESKTOP:~&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now you can clone repositories and open them in a Dev Container from within the WSL file system for increased performance. The performance is improved because WSL offers better integration with Docker.&lt;/li&gt;
&lt;li&gt;Alternatively, you can configure the WSL configuration file to open directly to the Linux home directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a Container?
&lt;/h2&gt;

&lt;p&gt;Docker containers allow you to run code in a defined, isolated environment. This ensures consistency and reliability, as the environment remains the same regardless of where the container is run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Up Next
&lt;/h2&gt;

&lt;p&gt;Next time, we'll cover running a container. We'll create an image using a Dockerfile and a sample application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful resources
&lt;/h2&gt;

&lt;p&gt;You can download docker here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.docker.com/"&gt;https://www.docker.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download the VS Code extensions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/devcontainers/containers"&gt;https://code.visualstudio.com/docs/devcontainers/containers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Developing inside a Container:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/devcontainers/containers"&gt;https://code.visualstudio.com/docs/devcontainers/containers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try out with different development environments:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/search?q=org%3Amicrosoft+vscode-remote-try-&amp;amp;type=Repositories"&gt;https://github.com/search?q=org%3Amicrosoft+vscode-remote-try-&amp;amp;type=Repositories&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Microsoft/vscode-remote-try-node"&gt;https://github.com/Microsoft/vscode-remote-try-node&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>containers</category>
      <category>wsl</category>
      <category>linux</category>
    </item>
    <item>
      <title>Fetching Data (Next.js)</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Tue, 30 Apr 2024 18:36:28 +0000</pubDate>
      <link>https://dev.to/samuellubliner/fetching-data-nextjs-5b0b</link>
      <guid>https://dev.to/samuellubliner/fetching-data-nextjs-5b0b</guid>
      <description>&lt;p&gt;You can view my commits on &lt;a href="https://github.com/Samuel-Lubliner/nextjs-dashboard/commit/7e2d57a4b34976dc490ba8726a860169e3042029"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ways to fetch data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;li&gt;ORMs&lt;/li&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API
&lt;/h2&gt;

&lt;p&gt;An API layer can be used to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interact with a 3rd party services that provide an API.&lt;/li&gt;
&lt;li&gt;Fetching data from the client.

&lt;ul&gt;
&lt;li&gt;API layer that runs on the server.&lt;/li&gt;
&lt;li&gt;avoid exposing database secrets to the client.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Next.js, create API endpoints using &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/route-handlers"&gt;Route Handlers&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database queries
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Logic to interact with a relational databases like Postgres with with SQL, or an ORM like Prisma.&lt;/li&gt;
&lt;li&gt;Write database queries when creating API endpoints and logic to interact with your database.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Server Components to fetch data
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js uses React Server Components by default.&lt;/li&gt;
&lt;li&gt;React server components fetch data on the server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits to fetching data with Server Components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server Components support promises, providing a simpler solution for asynchronous tasks.

&lt;ul&gt;
&lt;li&gt;Use async/await syntax without useEffect, useState or data fetching libraries.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Server Components execute on the server.

&lt;ul&gt;
&lt;li&gt;You can keep expensive data fetches and logic on the server and only send the result to the client.&lt;/li&gt;
&lt;li&gt;If using React server components you can skip the API layer, and query your database directly without exposing database secrets to the client.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using SQL
&lt;/h2&gt;

&lt;p&gt;For this dashboard project, I'll write database queries using the &lt;a href="https://vercel.com/docs/storage/vercel-postgres/sdk"&gt;Vercel Postgres SDK&lt;/a&gt; and SQL.&lt;/p&gt;

&lt;p&gt;Reasons to use SQL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL is the industry standard for querying relational databases.&lt;/li&gt;
&lt;li&gt;ORMs generate SQL under the hood.&lt;/li&gt;
&lt;li&gt;The Vercel Postgres SDK provides protection against SQL injections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;/app/lib/data.ts&lt;/code&gt;, query the database by importing the &lt;code&gt;sql&lt;/code&gt; function from &lt;code&gt;@vercel/postgressql&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching data for the dashboard overview page
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;/app/dashboard/page.tsx&lt;/code&gt;, &lt;code&gt;Page&lt;/code&gt; is an async component. This allows you to use await to fetch data. There are 3 components which receive data: &lt;code&gt;&amp;lt;Card&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;RevenueChart&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;LatestInvoices&amp;gt;&lt;/code&gt;. We fetch data by importing functions from &lt;code&gt;data.ts&lt;/code&gt; and calling them inside the components.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fetching with JS vs SQL
&lt;/h1&gt;

&lt;p&gt;Fetching and sorting the invoices using JavaScript can be inefficient. Instead of sorting through the latest invoices in-memory, you can use an SQL query to fetch only the last 5 invoices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerendering
&lt;/h2&gt;

&lt;p&gt;By default, Next.js utilizes Static Rendering to enhance performance. However, prerendering does not automatically update to reflect real-time changes in data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Request waterfall
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Network requests depending on the completion of previous requests.&lt;/li&gt;
&lt;li&gt;This can result in blocking data requests.&lt;/li&gt;
&lt;li&gt;Useful to satisfy a condition before making the next request.&lt;/li&gt;
&lt;li&gt;If the waterfall is unintentional, it can negatively impact performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Parallel data fetching
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Initiate all data requests at the same time to avoid waterfalls.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Promise.all()&lt;/code&gt; and &lt;code&gt;Promise.allSettled()&lt;/code&gt; initiate all promises at the same time.&lt;/li&gt;
&lt;li&gt;Executing all data fetches at the same time can lead to performance gains.&lt;/li&gt;
&lt;li&gt;Disadvantage: if one data request is slower than all the others.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>sql</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Setting Up Your Database (Next.js)</title>
      <dc:creator>Samuel Lubliner</dc:creator>
      <pubDate>Thu, 04 Apr 2024 19:07:48 +0000</pubDate>
      <link>https://dev.to/samuellubliner/setting-up-your-database-nextjs-9on</link>
      <guid>https://dev.to/samuellubliner/setting-up-your-database-nextjs-9on</guid>
      <description>&lt;p&gt;Here, I am setting up a PostgreSQL database using &lt;code&gt;@vercel/postgres&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vercel
&lt;/h2&gt;

&lt;p&gt;In Vercel, select and import a GitHub repository. Name your project and click Deploy. Connecting your GitHub repository will automatically redeploy your application, whenever you push changes to your main branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Postgres database
&lt;/h2&gt;

&lt;p&gt;Click Continue to Dashboard and select the Storage tab from your project dashboard. Select &lt;code&gt;Connect → Store → Create New → Postgres → Continue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Assign a name to your database and set the region. Place your database in a nearby region to reduce latency for data requests. Learn more about latency &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Understanding_latency"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tip: You cannot change the database region once it has been initialized. To use a different &lt;a href="https://vercel.com/docs/storage/vercel-postgres/limits#supported-regions"&gt;region&lt;/a&gt;, set it before creating a database.&lt;/p&gt;

&lt;p&gt;Once connected, navigate to the &lt;code&gt;.env.local&lt;/code&gt; tab, click &lt;code&gt;Show secret&lt;/code&gt; and &lt;code&gt;Copy Snippet&lt;/code&gt;. Paste the contents into your code editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Database Secrets
&lt;/h2&gt;

&lt;p&gt;Important: Don't expose database secrets when you push to GitHub. In &lt;code&gt;.gitignore&lt;/code&gt;, make sure &lt;code&gt;.env&lt;/code&gt; is in the ignored files. Finally, &lt;code&gt;run npm i @vercel/postgres&lt;/code&gt; to install the &lt;a href="https://vercel.com/docs/storage/vercel-postgres/sdk"&gt;Vercel Postgres SDK&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Seed the database
&lt;/h2&gt;

&lt;p&gt;Seeding the database allows you to have some data to work with as you build the dashboard.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/scripts/seed.js&lt;/code&gt; uses SQL to create the tables. The data from &lt;code&gt;placeholder-data.js&lt;/code&gt; file populates them.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;seed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node -r dotenv/config ./scripts/seed.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the command that will execute &lt;code&gt;seed.js&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Troubleshooting:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make sure to reveal your database secrets before copying it into your &lt;code&gt;.env&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;The script uses &lt;code&gt;bcrypt&lt;/code&gt; to hash the user's password, if &lt;code&gt;bcrypt&lt;/code&gt; isn't compatible with your environment, you can update the script to use &lt;code&gt;bcryptjs&lt;/code&gt; instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to run the script again, you can drop any existing tables by running &lt;code&gt;DROP TABLE tablename&lt;/code&gt; in your database query interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warning
&lt;/h3&gt;

&lt;p&gt;Be careful, this command will delete the tables and all their data. Do not run this command in a production app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring your database
&lt;/h2&gt;

&lt;p&gt;In Vercel click &lt;code&gt;Data&lt;/code&gt; on the sidenav. By selecting each table, you can view its records and ensure the entries align with the data from &lt;code&gt;placeholder-data.js&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executing queries
&lt;/h2&gt;

&lt;p&gt;Switch to the &lt;code&gt;query&lt;/code&gt; tab to interact with your database. This section supports SQL commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  You can view my commits on GitHub:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/Samuel-Lubliner/nextjs-dashboard/commit/75902d2771381dfc4cc659f149a0e469faf34931"&gt;Add postgress&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/Samuel-Lubliner/nextjs-dashboard/commit/1f63d2285c45c20170b3d462fda9cae98d012eb3"&gt;Add seed&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>database</category>
    </item>
  </channel>
</rss>
