<?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: Joshua Hassan</title>
    <description>The latest articles on DEV Community by Joshua Hassan (@joshthecodingaddict).</description>
    <link>https://dev.to/joshthecodingaddict</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%2F845953%2Feb019be9-2e4b-4ef1-9602-079ac79d2fdd.png</url>
      <title>DEV Community: Joshua Hassan</title>
      <link>https://dev.to/joshthecodingaddict</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joshthecodingaddict"/>
    <language>en</language>
    <item>
      <title>🚀 WSGI vs ASGI — Sync vs Async in Python Web Development (Made Simple)</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Mon, 07 Apr 2025 12:02:06 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/wsgi-vs-asgi-sync-vs-async-in-python-web-development-made-simple-50pp</link>
      <guid>https://dev.to/joshthecodingaddict/wsgi-vs-asgi-sync-vs-async-in-python-web-development-made-simple-50pp</guid>
      <description>&lt;p&gt;&lt;em&gt;Written with the assistance of AI (ChatGPT)&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 The Basics
&lt;/h3&gt;

&lt;p&gt;If you're building web apps with &lt;strong&gt;Flask&lt;/strong&gt;, &lt;strong&gt;Django&lt;/strong&gt;, or &lt;strong&gt;FastAPI&lt;/strong&gt;, you've probably heard terms like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  WSGI&lt;/li&gt;
&lt;li&gt;  ASGI&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sync&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Async&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Blocking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Non-blocking&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But what do these actually mean for &lt;strong&gt;you&lt;/strong&gt; as a developer?&lt;/p&gt;

&lt;p&gt;Let’s break it down — simply.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔄 WSGI vs ASGI
&lt;/h3&gt;

&lt;p&gt;When building web apps in Python, WSGI (Web Server Gateway Interface) and ASGI (Asynchronous Server Gateway Interface) determine how requests are handled and how your server communicates with your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WSGI&lt;/strong&gt; is the traditional standard used by synchronous Python web frameworks like Flask and Django. It processes one request per thread, meaning it blocks the thread until that request is completed. This is fine for low-traffic apps but can cause slowdowns when handling many concurrent users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ASGI&lt;/strong&gt;, on the other hand, was introduced to support asynchronous operations and handle concurrency. It allows multiple requests to be processed at the same time using async/await. This makes it ideal for modern frameworks like FastAPI and Django Channels, which need to handle high traffic or tasks like real-time updates, long-running operations, or handling I/O-bound operations (e.g., database queries, API calls).&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;p&gt;WSGI: One thread, one request at a time.&lt;/p&gt;

&lt;p&gt;ASGI: Multiple threads (or coroutines), multiple requests at once.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧱 Synchronous (WSGI)
&lt;/h3&gt;

&lt;p&gt;In a synchronous world (like using Flask), each request blocks the thread it's running on until it's done:&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sync_x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Simulates a long task
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User A calls &lt;code&gt;/X&lt;/code&gt; → sleeps for 5 sec&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;During this, &lt;strong&gt;no other requests&lt;/strong&gt; can be handled (on a single worker)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User B or C? They &lt;strong&gt;wait&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unless you scale with multiple threads or processes, your app becomes slow under load.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚡ Asynchronous (ASGI)
&lt;/h3&gt;

&lt;p&gt;With frameworks like &lt;strong&gt;FastAPI&lt;/strong&gt;, you can write non-blocking code using &lt;code&gt;async def&lt;/code&gt; and &lt;code&gt;await&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="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/X&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;async_x&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Simulated non-blocking delay
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefit&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User A hits &lt;code&gt;/X&lt;/code&gt; and awaits&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While waiting, the server &lt;strong&gt;handles User B and User C&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All requests proceed &lt;strong&gt;without blocking&lt;/strong&gt; each other&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧪 Real-World Scenario: 3 Users, Same Endpoint
&lt;/h3&gt;

&lt;h4&gt;
  
  
  SYNC Version (blocking):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/sync&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sync_endpoint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sync response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  ASYNC Version (non-blocking):
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/async&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;async_endpoint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Async response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Test&lt;/strong&gt;:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6okagn5mne1j93nx3wnl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6okagn5mne1j93nx3wnl.png" alt="tests" width="528" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sync&lt;/strong&gt;: Each request waits its turn&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Async&lt;/strong&gt;: All requests run at the same time&lt;/p&gt;

&lt;p&gt;That’s the power of &lt;strong&gt;non-blocking&lt;/strong&gt; code.&lt;/p&gt;


&lt;h3&gt;
  
  
  🤔 Wait… Doesn’t &lt;code&gt;await&lt;/code&gt; Still “Wait”?
&lt;/h3&gt;

&lt;p&gt;Yes! But only &lt;strong&gt;your coroutine&lt;/strong&gt; pauses — the &lt;strong&gt;event loop keeps going&lt;/strong&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;some_async_call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Your function pauses at &lt;code&gt;await&lt;/code&gt;, but the server is free to do other things.&lt;br&gt;&lt;br&gt;
When &lt;code&gt;some_async_call()&lt;/code&gt; completes, your code resumes with &lt;code&gt;b = a + 1&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  🌀 What is a Coroutine?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;coroutine&lt;/strong&gt; is a special type of function that can pause and resume its execution — perfect for handling I/O tasks like API calls, database queries, or sleep timers &lt;strong&gt;without blocking&lt;/strong&gt; the main thread.&lt;/p&gt;

&lt;p&gt;In Python, any function defined with &lt;code&gt;async def&lt;/code&gt; is a coroutine:&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;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Coroutines give you concurrency without threads — they’re lightweight, efficient, and ideal for high-performance web apps.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 Final Thoughts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;WSGI&lt;/strong&gt; (sync) for simple apps or when working with older libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;ASGI&lt;/strong&gt; (async) for modern apps that need speed, scale, or handle I/O (DBs, APIs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Even a simple change like switching from &lt;code&gt;time.sleep()&lt;/code&gt; to &lt;code&gt;await asyncio.sleep()&lt;/code&gt; can unlock huge performance gains.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  💬 TL;DR
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Sync (WSGI)&lt;/th&gt;
&lt;th&gt;Async (ASGI)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Blocking&lt;/td&gt;
&lt;td&gt;Yes (per request)&lt;/td&gt;
&lt;td&gt;No (per request)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency&lt;/td&gt;
&lt;td&gt;Threads/Processes&lt;/td&gt;
&lt;td&gt;Coroutines (cheap!)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Popular With&lt;/td&gt;
&lt;td&gt;Flask, Django (classic)&lt;/td&gt;
&lt;td&gt;FastAPI, Django (ASGI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Good (low traffic)&lt;/td&gt;
&lt;td&gt;Excellent (high traffic)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  📚 References and Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Real Python: &lt;a href="https://realpython.com/async-io-python/" rel="noopener noreferrer"&gt;Async IO in Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ASGI Spec: &lt;a href="https://asgi.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;asgi.readthedocs.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FastAPI Docs: &lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;fastapi.tiangolo.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Django Async Support: &lt;a href="https://docs.djangoproject.com/en/stable/topics/async/" rel="noopener noreferrer"&gt;docs.djangoproject.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WSGI Spec: &lt;a href="https://wsgi.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;wsgi.readthedocs.io&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Building a Decentralized Voting System with Smart Contracts</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Thu, 05 Sep 2024 11:08:55 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/building-a-decentralized-voting-system-with-smart-contracts-2k8</link>
      <guid>https://dev.to/joshthecodingaddict/building-a-decentralized-voting-system-with-smart-contracts-2k8</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What are Smart Contracts?&lt;/li&gt;
&lt;li&gt;Smart Contracts in Voting&lt;/li&gt;
&lt;li&gt;Building a Voting System with Smart Contracts&lt;/li&gt;
&lt;li&gt;Key Variables in Our Voting Smart Contract&lt;/li&gt;
&lt;li&gt;Key Functions of Our Voting Smart Contract&lt;/li&gt;
&lt;li&gt;Benefits and Challenges&lt;/li&gt;
&lt;li&gt;Resources to Learn More&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What are Smart Contracts?
&lt;/h2&gt;

&lt;p&gt;Imagine a vending machine. You put in money, press a button, and get your snack. No human needed to make this transaction happen. That's the basic idea behind a smart contract!&lt;/p&gt;

&lt;p&gt;A smart contract is like a digital vending machine. It's a computer program that automatically executes actions when certain conditions are met. Here's what makes them special:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automatic&lt;/strong&gt;: They run by themselves once they're set up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trustless&lt;/strong&gt;: You don't need to trust a middleman. The code ensures everything happens as agreed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparent&lt;/strong&gt;: Everyone can see the contract's code and how it works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt;: They're stored on a blockchain, making them very hard to hack or change.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In simple terms, smart contracts are "if-then" statements on a blockchain. If something happens, then a specific action is taken.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart Contracts in Voting
&lt;/h2&gt;

&lt;p&gt;Now, let's think about how we could use a smart contract for voting. It could work like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up the election (like setting up our vending machine)&lt;/li&gt;
&lt;li&gt;Register voters (like giving people the right coins for our machine)&lt;/li&gt;
&lt;li&gt;Cast votes (like pressing buttons on the machine)&lt;/li&gt;
&lt;li&gt;Count votes and declare results (like the machine dispensing the most-chosen snack)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of this happens automatically, securely, and transparently. No one can stuff the ballot box or change votes without everyone noticing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Voting System with Smart Contracts
&lt;/h2&gt;

&lt;p&gt;Let's look at how we might build a simple voting system using a smart contract. We'll use a language called Solidity, which is commonly used for writing smart contracts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract VotingDApp {
    // Contract code will go here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the shell of our contract. Now, let's fill it with some useful parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Variables in Our Voting Smart Contract
&lt;/h2&gt;

&lt;p&gt;Let's break down the main variables used in our contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;address public owner;
uint256 public pollCount;
mapping(uint256 =&amp;gt; Poll) public polls;
mapping(address =&amp;gt; bool) public registeredCandidates;
mapping(uint256 =&amp;gt; mapping(address =&amp;gt; Candidate)) public pollCandidates;
mapping(uint256 =&amp;gt; address[]) public allCandidates;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what each of these does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;owner&lt;/code&gt;: This stores the Ethereum address of the person who created the contract. They have special permissions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pollCount&lt;/code&gt;: This keeps track of how many polls have been created. It's like a counter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;polls&lt;/code&gt;: This is a way to store all the polls. Each poll has a number (its ID), and this mapping links that number to all the poll's information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;registeredCandidates&lt;/code&gt;: This keeps track of which Ethereum addresses have registered as candidates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pollCandidates&lt;/code&gt;: This is a bit more complex. It stores information about candidates for each poll. You can look up a candidate by the poll ID and the candidate's address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;allCandidates&lt;/code&gt;: This stores a list of all candidate addresses for each poll.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These variables help us keep track of all the information we need for our voting system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Functions of Our Voting Smart Contract
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Creating a Poll
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createPoll(string memory name, string memory imageUrl, uint256 startTime, uint256 endTime) public onlyOwner {
    require(startTime &amp;lt; endTime, "Invalid poll duration");

    pollCount++;
    Poll storage poll = polls[pollCount];
    poll.name = name;
    poll.imageUrl = imageUrl;
    poll.active = false;
    poll.startTime = startTime;
    poll.endTime = endTime;

    emit PollCreated(pollCount, name, imageUrl, startTime, endTime);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function is like setting up a new election. Here's what it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only the owner can create a poll (that's what &lt;code&gt;onlyOwner&lt;/code&gt; means)&lt;/li&gt;
&lt;li&gt;It checks that the end time is after the start time&lt;/li&gt;
&lt;li&gt;It creates a new poll with a name, image, start time, and end time&lt;/li&gt;
&lt;li&gt;It tells everyone a new poll has been created (that's what &lt;code&gt;emit&lt;/code&gt; does)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Registering as a Candidate
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function registerAsCandidate(uint256 pollId, string memory candidateName, string memory imageUrl) public pollExists(pollId) {
    require(pollCandidates[pollId][msg.sender].candidateAddress == address(0), "Already registered as a candidate");
    require(!isCandidateNameTaken(pollId, candidateName), "Candidate name already taken");

    pollCandidates[pollId][msg.sender] = Candidate({
        candidateAddress: msg.sender,
        name: candidateName,
        imageUrl: imageUrl,
        approved: false,
        votesReceived: 0
    });

    allCandidates[pollId].push(msg.sender);

    emit CandidateRegistered(pollId, msg.sender, candidateName, imageUrl);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function lets someone sign up to be a candidate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It checks that the poll exists and the person hasn't already registered&lt;/li&gt;
&lt;li&gt;It makes sure the candidate name isn't already taken&lt;/li&gt;
&lt;li&gt;It creates a new candidate with their name, image, and address&lt;/li&gt;
&lt;li&gt;It tells everyone a new candidate has registered&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Voting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function vote(uint256 pollId, address candidate) public {
    Poll storage poll = polls[pollId];
    require(poll.active, "Poll is not active");
    require(!poll.hasVoted[msg.sender], "Already voted");
    require(pollCandidates[pollId][candidate].approved, "Candidate not approved");

    poll.hasVoted[msg.sender] = true;
    poll.votes[candidate]++;
    poll.totalVotes++;
    pollCandidates[pollId][candidate].votesReceived++;

    if (poll.votes[candidate] &amp;gt; poll.highestVotes) {
        poll.highestVotes = poll.votes[candidate];
        poll.winner = candidate;
    }

    emit VoteCasted(pollId, msg.sender, candidate);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the actual voting function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It checks that the poll is active and the voter hasn't already voted&lt;/li&gt;
&lt;li&gt;It makes sure the candidate is approved&lt;/li&gt;
&lt;li&gt;It records the vote and updates the vote count&lt;/li&gt;
&lt;li&gt;If this candidate now has the most votes, it updates the winner&lt;/li&gt;
&lt;li&gt;It tells everyone that a vote has been cast&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Ending a Poll
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function endPoll(uint256 pollId) public onlyOwner pollExists(pollId) {
    require(polls[pollId].active, "Poll is not active");

    polls[pollId].active = false;

    emit PollEnded(pollId, polls[pollId].winner);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function ends a poll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only the owner can end a poll&lt;/li&gt;
&lt;li&gt;It checks that the poll exists and is active&lt;/li&gt;
&lt;li&gt;It marks the poll as inactive&lt;/li&gt;
&lt;li&gt;It announces that the poll has ended and who the winner is&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits and Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: It's very hard to cheat or hack the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency&lt;/strong&gt;: Everyone can see how the voting works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt;: No need for manual counting or management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;: People could potentially vote from anywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Technical Knowledge&lt;/strong&gt;: It can be complicated for some people to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: Running smart contracts on a blockchain can be expensive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: It might be hard to handle very large elections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy&lt;/strong&gt;: Balancing transparency with voter privacy can be tricky.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources to Learn More
&lt;/h2&gt;

&lt;p&gt;If you're interested in learning more about smart contracts and blockchain technology, here are some great resources:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://ethereum.org/en/smart-contracts/" rel="noopener noreferrer"&gt;Ethereum.org's Introduction to Smart Contracts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.soliditylang.org/" rel="noopener noreferrer"&gt;Solidity Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cryptozombies.io/" rel="noopener noreferrer"&gt;CryptoZombies&lt;/a&gt; - A fun, interactive way to learn Solidity&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://consensys.net/academy/" rel="noopener noreferrer"&gt;ConsenSys Academy&lt;/a&gt; - Offers courses on blockchain development&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.openzeppelin.com/learn/" rel="noopener noreferrer"&gt;OpenZeppelin Learn&lt;/a&gt; - Tutorials and guides on smart contract development&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Smart contracts offer an exciting new way to run voting systems. They can make voting more secure, transparent, and efficient. While there are challenges to overcome, the potential benefits make this an area worth exploring and developing further.&lt;/p&gt;

&lt;p&gt;Remember, this is a simplified example. Real-world voting systems would need additional features and rigorous security measures. But hopefully, this gives you a good starting point for understanding how smart contracts can be used in voting!&lt;/p&gt;

&lt;p&gt;You can find the full code for this voting system on GitHub: &lt;a href="https://github.com/skynette/web3-voting/blob/main/web3/VotingDApp.sol" rel="noopener noreferrer"&gt;VotingDApp Smart Contract&lt;/a&gt;&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>web3</category>
      <category>tutorial</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Mastering Soft Delete</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Sun, 31 Dec 2023 16:25:41 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/mastering-soft-delete-284a</link>
      <guid>https://dev.to/joshthecodingaddict/mastering-soft-delete-284a</guid>
      <description>&lt;p&gt;Have you ever wondered what happens to that cute puppy picture you accidentally deleted from your phone? Vanished to digital oblivion? Not quite! There's a secret world in databases where deleted data isn't gone, it's just playing hide-and-seek. This magical trick is called &lt;strong&gt;soft delete&lt;/strong&gt;, and it's a superhero for developers like you and me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imagine this:&lt;/strong&gt; You're building a shopping app, and a customer accidentally removes their dream sneakers from their cart. Panic sets in, right? But not if you have soft delete! Instead of disappearing forever, those sneakers simply move to a special corner of the database, marked as "deleted" but still ready to be rescued. This gives you the chance to be the digital hero, swooping in to restore the order and save the day (and the customer's shopping spree).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is soft delete so awesome?&lt;/strong&gt; Think of it as a safety net for your database:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accidentally erased your grandma's recipe in your recipe app?&lt;/strong&gt; No worries, soft delete brings it back with a snap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Need to track who deleted what and when?&lt;/strong&gt; Soft delete keeps an audit log, like a digital detective, making it easy to solve database mysteries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worried about deleting something connected to other things?&lt;/strong&gt; Soft delete handles relationships like a pro, ensuring everything stays balanced and happy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But hey, just like any power, soft delete needs training. Here's how you can wield it like a coding wizard in Django:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Building the Secret Hideout:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a special "SoftDeleteModel" that has a magic field called &lt;code&gt;deleted_at&lt;/code&gt;. This field acts like a timer, marking the moment something went into hiding. Then, all your other models can inherit this power, making them soft-delete masters!&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SoftDeleteManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;with_deleted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get_queryset&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SoftDeleteModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SoftDeleteManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;soft_delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deleted_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;YourModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SoftDeleteModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# other fields go here
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Finding the Hidden Treasures:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By default, only the living see the living. To see the ghosts in your database, you need to say the magic words: &lt;code&gt;objects.with_deleted()&lt;/code&gt;. This reveals the hidden treasures, letting you see everything, even the deleted stuff.&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="c1"&gt;# To retrieve deleted and non-deleted records
&lt;/span&gt;&lt;span class="n"&gt;YourModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_deleted&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# To retrieve only non-deleted records
&lt;/span&gt;&lt;span class="n"&gt;YourModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Bringing Back the Lost Souls:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Want to bring a deleted item back to life? Easy! Just set the &lt;code&gt;deleted_at&lt;/code&gt; timer back to zero, and poof! It's back in the land of the living, ready to be used again.&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="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;YourModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;restore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; Soft delete is a powerful tool, but with great power comes great responsibility. Make sure you have good reasons for keeping deleted things around, and don't let your database become a haunted house of forgotten data.&lt;/p&gt;

&lt;p&gt;Now, go forth and conquer the world of soft delete! Remember, it's not just about saving data, it's about saving the day (and maybe preventing a few tears along the way). And who knows, maybe you'll even inspire other newbie developers to embrace the power of the disappearing act!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus Tips for the Superheroes of Tomorrow:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check out libraries like &lt;a href="https://pypi.org/project/django-safedelete/" rel="noopener noreferrer"&gt;django-safedelete&lt;/a&gt;, &lt;a href="https://pypi.org/project/django-soft-delete/" rel="noopener noreferrer"&gt;django-soft-delete&lt;/a&gt; and &lt;a href="https://pypi.org/project/django-paranoid/" rel="noopener noreferrer"&gt;django-paranoid&lt;/a&gt; for extra soft-delete superpowers.&lt;/li&gt;
&lt;li&gt;Remember, even soft-deleted data takes up space, so have a plan for cleaning up the digital graveyard every now and then.&lt;/li&gt;
&lt;li&gt;And most importantly, have fun and experiment! Soft delete is a playground for your coding creativity, so go wild and build amazing things!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>learning</category>
      <category>architecture</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Write Faster Django Queries</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Wed, 22 Feb 2023 15:17:07 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/write-faster-django-queries-mgc</link>
      <guid>https://dev.to/joshthecodingaddict/write-faster-django-queries-mgc</guid>
      <description>&lt;p&gt;Hi readers, I was recently working on a team project when I encountered inefficient and redundant code. To address this issue, I researched and experimented with various techniques for optimizing Django queries, which led to the creation of this article. Regardless of your experience level with Django, this article aims to equip you with the necessary tools to enhance the performance of your applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TABLE OF CONTENTS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Introduction
&lt;/li&gt;
&lt;li&gt;  Prerequisites
&lt;/li&gt;
&lt;li&gt;  What is Django ORM
&lt;/li&gt;
&lt;li&gt;  How to view database performance
&lt;/li&gt;
&lt;li&gt; The N+1 problem
&lt;/li&gt;
&lt;li&gt; Ways to write faster and more efficient queries

&lt;ul&gt;
&lt;li&gt;Use select_related() and prefetch_related():&lt;/li&gt;
&lt;li&gt;Use filter() instead of get()&lt;/li&gt;
&lt;li&gt;Use only() or defer()&lt;/li&gt;
&lt;li&gt;Use subqueries&lt;/li&gt;
&lt;li&gt;Use Q objects for complex queries&lt;/li&gt;
&lt;li&gt;Use annotations&lt;/li&gt;
&lt;li&gt;Use aggregation&lt;/li&gt;
&lt;li&gt;Use caching&lt;/li&gt;
&lt;li&gt;Honorable mentions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  Conclusion
&lt;/li&gt;

&lt;li&gt;  References
&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Developers prioritize building web applications that are efficient and scalable, and optimizing database queries is crucial to achieving these goals. Django's built-in Object-Relational Mapping (ORM) allows developers to interact with the database without writing complex SQL queries. However, poorly optimized queries can result in slow performance and increased server load. In this article, we'll discuss techniques for writing faster Django queries and improving your application's overall performance.&lt;/p&gt;

&lt;p&gt;At the end of the article, readers will have gained a better understanding of how to write optimized queries, and will be able to implement these techniques in their own applications. Additionally, readers will have gained a deeper understanding of how the Django ORM works, and will be able to use this knowledge to make informed decisions when working with databases in their projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge of &lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Basic Knowledge of &lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;Django&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Basic Knowledge of &lt;a href="https://opensource.com/article/17/11/django-orm" rel="noopener noreferrer"&gt;Django-Orm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Django ORM
&lt;/h2&gt;

&lt;p&gt;The Django web framework provides a built-in tool called Object-Relational Mapping (ORM), which enables developers to interact with relational databases using high-level Python objects instead of writing complex SQL queries. The ORM maps database tables to Python classes, and database rows to instances of those classes, providing a simple and intuitive way to perform CRUD (create, read, update, and delete) operations on the database. This abstraction layer simplifies working with databases, removes the need to deal with low-level details, and reduces the risk of SQL injection attacks. Moreover, the Django ORM is compatible with a variety of databases, such as PostgreSQL, MySQL, SQLite, and Oracle.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to view database performance
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;You can use the Django Debug Toolbar to view DB performance. The below link is for Django Debug Toolbar documentation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://django-debug-toolbar.readthedocs.io/en/latest/installation.html" rel="noopener noreferrer"&gt;https://django-debug-toolbar.readthedocs.io/en/latest/installation.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use QuerySet.explain() to understand how specific QuerySets are executed by your database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use django silk to view DB performance. &lt;a href="https://github.com/jazzband/django-silk" rel="noopener noreferrer"&gt;https://github.com/jazzband/django-silk&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But in this guide, we will be using the first option&lt;/p&gt;

&lt;h2&gt;
  
  
  The N+1 problem
&lt;/h2&gt;

&lt;p&gt;The N+1 problem is a common issue that can occur in ORM frameworks, including Django. It arises when you fetch a collection of objects and then iterate over them to access a related object. This can lead to N+1 database queries being executed, where N is the number of objects you're iterating over.&lt;/p&gt;

&lt;p&gt;For example, suppose you have a &lt;code&gt;Book&lt;/code&gt; model with an &lt;code&gt;author&lt;/code&gt; ForeignKey field, and you want to display a list of books with their author names. If you retrieve a queryset of all books and iterate over them to access the author names, Django will execute a separate database query for each book to retrieve its associated author. This can lead to a significant number of database queries being executed, which can slow down your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ways to write faster and more efficient queries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Use select_related() and prefetch_related():
&lt;/h3&gt;

&lt;p&gt;These methods are used to optimize database queries by reducing the number of database queries. select_related() is used to retrieve related objects in one database query, while prefetch_related() is used to retrieve multiple sets of related objects in one database query.&lt;/p&gt;

&lt;p&gt;Suppose you have two models, &lt;code&gt;Author&lt;/code&gt; and &lt;code&gt;Book&lt;/code&gt;, where each book has an author&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="kn"&gt;from&lt;/span&gt;  &lt;span class="n"&gt;django.db&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;  &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name_plural&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;authors&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;  &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;book&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;verbose_name_plural&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;books&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here are three versions of a view that retrieves a list of books and their authors using the Django ORM. The first version is a simple implementation that retrieves the data using two separate queries,  the second version optimizes the queries using &lt;code&gt;select_related()&lt;/code&gt; and the third version optimizes the queries using &lt;code&gt;prefetch_related()&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="c1"&gt;# Version 1 - Simple implementation
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;books&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;book_list.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Version 2 - Optimized implementation using select_related()
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_related&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;books&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;book_list.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Version 3 - Optimized implementation using prefetch_related()
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prefetch_related&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;book_list.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;books&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;booklist.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% for  book  in  books %}
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-1/2 px-4 mb-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-white shadow-lg rounded-lg overflow-hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ book.title }}&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-700"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ book.author }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt;  &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-gray-700 mt-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ book.description }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

{% endfor %}

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the first version, the books are retrieved using a single query (&lt;code&gt;Book.objects.all()&lt;/code&gt;), but a separate query is executed for each author (&lt;code&gt;book.author&lt;/code&gt; in the for loop). This can lead to the N+1 query problem if there are many books and authors in the database, as it will result in a large number of queries being executed.&lt;/li&gt;
&lt;/ul&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%2F73bilw251et1ienl52q0.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%2F73bilw251et1ienl52q0.png" alt="unoptimized result" width="800" height="383"&gt;&lt;/a&gt;&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%2Ftcgvm73rharuixdqlrl2.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%2Ftcgvm73rharuixdqlrl2.png" alt="unoptimized 6 queries" width="800" height="233"&gt;&lt;/a&gt;&lt;br&gt;
we are having 6 queries&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The second version of the view is optimized because it reduces the number of queries that need to be executed. The &lt;code&gt;select_related()&lt;/code&gt; method is used to retrieve the related author objects in the same query as the books, using a join operation. This means that only one query is executed, regardless of the number of books and authors in the database. By reducing the number of queries, the second version of the view is more optimized than the first version.&lt;/li&gt;
&lt;/ul&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%2Fci4m59osi9t7vsxt7rr3.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%2Fci4m59osi9t7vsxt7rr3.png" alt="Optimized to 1 query" width="800" height="246"&gt;&lt;/a&gt;&lt;br&gt;
reduced to 1 query&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The third version of the view is also optimized, but it uses a different technique called &lt;code&gt;prefetch_related()&lt;/code&gt;. This method is useful when you want to retrieve related objects that are not directly related to the main object being queried (in this case, &lt;code&gt;Book&lt;/code&gt;). In the &lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;Author&lt;/code&gt; model, there is a foreign key relationship between the two models, and &lt;code&gt;select_related()&lt;/code&gt; works perfectly to optimize the query. However, if the &lt;code&gt;Author&lt;/code&gt; model had a foreign key relationship with another model, say &lt;code&gt;Publisher&lt;/code&gt;, and you wanted to retrieve all the books written by authors and the publisher information for each book, &lt;code&gt;select_related()&lt;/code&gt; would not work in this case because it only works with directly related models.&lt;/p&gt;

&lt;p&gt;In such cases, you can use &lt;code&gt;prefetch_related()&lt;/code&gt; to retrieve the related objects in a separate query. In the third version of the view, &lt;code&gt;prefetch_related('author')&lt;/code&gt; is used to retrieve all the authors for the books in a single query. This technique is particularly useful when you have many related objects and need to optimize the queries while minimizing the number of database hits.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;prefetch_related()&lt;/code&gt; in the third version of the view, Django retrieves all the related author objects in a single query and caches them for use in the template. This results in faster query execution times and reduces the number of database hits, especially when dealing with large datasets.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&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%2Fdahj6aweu3tb0jbn0pk8.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%2Fdahj6aweu3tb0jbn0pk8.png" alt="Optimized to 2 queries" width="800" height="256"&gt;&lt;/a&gt;&lt;br&gt;
optimized to 2 queries&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Use filter() instead of get():
&lt;/h3&gt;

&lt;p&gt;When retrieving a single object from the database using the Django ORM, you have two options: &lt;code&gt;get()&lt;/code&gt; or &lt;code&gt;filter()&lt;/code&gt;. Both methods are used to retrieve an object based on a set of conditions, but they behave differently.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;get()&lt;/code&gt; retrieves a single object that matches the specified conditions, or raises an exception if no object is found or more than one object is found. For example, to retrieve a user with a specific email address, you can use the following code:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user@example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other hand, &lt;code&gt;filter()&lt;/code&gt; retrieves a QuerySet of objects that match the specified conditions. For example, to retrieve all users with a specific first name, you can use the following code:&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="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you use &lt;code&gt;get()&lt;/code&gt; to retrieve a single object, Django makes a single database query to retrieve the object. However, if the specified conditions match more than one object, &lt;code&gt;get()&lt;/code&gt; raises a &lt;code&gt;MultipleObjectsReturned&lt;/code&gt; exception. If no object is found, &lt;code&gt;get()&lt;/code&gt; raises a &lt;code&gt;DoesNotExist&lt;/code&gt; exception.&lt;/p&gt;

&lt;p&gt;When you use &lt;code&gt;filter()&lt;/code&gt; to retrieve a single object, Django still makes two database queries: one to retrieve the matching objects, and another to retrieve the first object from the matching objects. However, you can avoid making the second query by using the &lt;code&gt;first()&lt;/code&gt; method to retrieve the first object from the QuerySet. For example:&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="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user@example.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code retrieves the first user that matches the email address, or returns &lt;code&gt;None&lt;/code&gt; if no matching user is found.&lt;/p&gt;

&lt;p&gt;In summary, using &lt;code&gt;filter()&lt;/code&gt; instead of &lt;code&gt;get()&lt;/code&gt; when retrieving a single object can reduce the number of database queries by avoiding exceptions and allowing you to retrieve the first object from a QuerySet instead of making a separate query.    &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use only() or defer():
&lt;/h3&gt;

&lt;p&gt;When querying a model, Django retrieves all fields of that model by default. However, in many cases, you may not need all fields for a particular query. This can lead to unnecessary database queries, which can impact performance.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;only()&lt;/code&gt; method, you can specify the fields you need for a particular query, which will limit the amount of data retrieved from the database. This can help reduce the number of queries and minimize the amount of data transferred over the network, which can improve the overall performance of your application.&lt;/p&gt;

&lt;p&gt;Similarly, using the &lt;code&gt;defer()&lt;/code&gt; method, you can exclude fields that are not needed for a particular query. This can be especially useful for fields that contain large amounts of data, such as binary data or large text fields. Excluding these fields from the query can help reduce the amount of data transferred over the network and improve the performance of your application.&lt;/p&gt;

&lt;p&gt;Suppose you have a model &lt;code&gt;User&lt;/code&gt; with many fields, but you only need to retrieve the username and email fields. You can use the &lt;code&gt;only()&lt;/code&gt; method to limit the fields returned by the query:&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="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;only&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will retrieve all users with only their username and email fields in a single query, instead of retrieving all fields for each user.&lt;/p&gt;

&lt;p&gt;Alternatively, suppose you have a model &lt;code&gt;User&lt;/code&gt; with many fields, but you don't need to retrieve the password field. You can use the &lt;code&gt;defer()&lt;/code&gt; method to exclude the password field from the query:&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="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will retrieve all users with all fields except the password field in a single query.&lt;/p&gt;

&lt;p&gt;Overall, using &lt;code&gt;only()&lt;/code&gt; and &lt;code&gt;defer()&lt;/code&gt; can be a powerful technique for optimizing your Django application's performance by reducing the amount of data retrieved from the database and minimizing the number of queries executed.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Use subqueries
&lt;/h3&gt;

&lt;p&gt;Subqueries can be used to retrieve related data in a more efficient way. For example, if you need to retrieve the count of related objects for each object in a queryset, you can use a subquery instead of using a loop.&lt;/p&gt;

&lt;p&gt;Suppose you have two models, &lt;code&gt;Author&lt;/code&gt; and &lt;code&gt;Book&lt;/code&gt;, where each book has an author. If you want to retrieve a list of authors with the count of their books, you could use a loop to iterate through each author and count their books. However, this approach would result in multiple database queries and slow performance for large datasets. Instead, you can use a subquery to retrieve the count of books for each author in a single query.&lt;/p&gt;

&lt;p&gt;Here's an example of the inefficient solution using a loop:&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;def&lt;/span&gt;  &lt;span class="nf"&gt;number_of_author_books&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;authors&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;  &lt;span class="n"&gt;author&lt;/span&gt;  &lt;span class="ow"&gt;in&lt;/span&gt;  &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;count&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;author_books.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;authors&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the loop iterates through each author and retrieves the count of books using a separate database query for each author. This can result in slow performance, especially for large datasets.&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%2Fl86tufhl15rv8k84o58t.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%2Fl86tufhl15rv8k84o58t.png" alt="unoptimized 3 queries" width="800" height="261"&gt;&lt;/a&gt;&lt;br&gt;
We have 3 queries&lt;/p&gt;

&lt;p&gt;Now, here's an example of the optimized solution using a subquery:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OuterRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Subquery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;  &lt;span class="nf"&gt;number_of_author_books_optimized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;authors&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;book_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Subquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;OuterRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;pk&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;author&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;author_books.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;authors&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;annotate()&lt;/code&gt; method is used to add a &lt;code&gt;book_count&lt;/code&gt; field to each author.  The resulting &lt;code&gt;authors&lt;/code&gt; queryset is passed to the &lt;code&gt;author_books.html&lt;/code&gt; template, which displays the author's name and the number of books they've written in a table.&lt;br&gt;
 The &lt;code&gt;Subquery&lt;/code&gt; function is used to retrieve the count of books for each author in a subquery, which is more efficient than using a loop. The &lt;code&gt;OuterRef&lt;/code&gt; function is used to reference the &lt;code&gt;pk&lt;/code&gt; of the outer query (i.e., the &lt;code&gt;Author&lt;/code&gt; queryset), and the &lt;code&gt;[:1]&lt;/code&gt; slice is used to limit the subquery to return only the first value.&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%2Fpi2l5hsxyt8r40i1rqj0.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%2Fpi2l5hsxyt8r40i1rqj0.png" alt="optimized to 1 query" width="800" height="274"&gt;&lt;/a&gt;&lt;br&gt;
We now optimized to have 1 query&lt;/p&gt;

&lt;p&gt;here is the html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% extends 'base.html' %}

{% block content %}
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-7xl mx-auto py-6 sm:px-6 lg:px-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-white overflow-hidden shadow-xl sm:rounded-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"min-w-full divide-y divide-gray-200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;thead&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-50"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        Author
                    &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;th&lt;/span&gt; &lt;span class="na"&gt;scope=&lt;/span&gt;&lt;span class="s"&gt;"col"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        Number of Books
                    &lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tbody&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-white divide-y divide-gray-200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                {% for author in authors %}
                &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"px-6 py-4 whitespace-nowrap"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm font-medium text-gray-900"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ author.name }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"px-6 py-4 whitespace-nowrap"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm font-medium text-gray-900"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ author.count }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm font-medium text-gray-900"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ author.book_count  }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                {% endfor %}
            &lt;span class="nt"&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using a subquery, we can retrieve the count of books for each author in a single database query, resulting in much faster performance compared to using a loop.&lt;/p&gt;

&lt;p&gt;Subqueries can be a highly effective method for fetching related data in a more efficient manner, particularly for complex or large datasets. Nevertheless, it is crucial to exercise caution while using subqueries and to evaluate their performance for your particular use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Use Q objects for complex queries:
&lt;/h3&gt;

&lt;p&gt;Q objects allow you to create complex queries with multiple conditions. They are especially useful when combining multiple conditions with OR or NOT operators.&lt;/p&gt;

&lt;p&gt;Here is an example of an inefficient query that uses multiple filter conditions:&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="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;author__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;publisher__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Penguin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;genre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Romance&lt;/span&gt;&lt;span class="sh"&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 query retrieves all books written by an author named John, published by Penguin, and excludes any books with the genre 'Romance'. However, this can get messy and hard to read when dealing with many conditions.&lt;/p&gt;

&lt;p&gt;Using Q objects, we can simplify this query by combining multiple conditions using OR or NOT operators:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Q&lt;/span&gt;

&lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publisher__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Penguin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Romance&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publisher__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Penguin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&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 query retrieves all books written by an author named John or published by Penguin, and excludes any books with the genre 'Romance' and published by Penguin.&lt;/p&gt;

&lt;p&gt;By using Q objects, we can write more concise and readable queries, while also improving query performance by reducing the number of database hits.&lt;/p&gt;

&lt;p&gt;It's important to note that using too many Q objects or nesting them too deeply can also have a negative impact on performance. It's important to strike a balance between readability and efficiency when using Q objects.&lt;/p&gt;

&lt;p&gt;Here is an example of a nested Q object that could potentially be inefficient:&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="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publisher__name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Penguin&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
        &lt;span class="nc"&gt;Q&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;genre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mystery&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this query, we are retrieving all books written by an author named John or published by Penguin with the genre 'Mystery'. However, this query could potentially be slow if the database has to perform many nested queries to retrieve the results. In cases like this, it may be better to break the query into multiple simpler queries instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Use annotations:
&lt;/h3&gt;

&lt;p&gt;In Django, annotations offer a way to supplement the queryset with additional information that isn't stored in the database. Annotations come in handy when you need to compute aggregate values or perform computations on associated objects. Employing annotations enables you to sidestep executing multiple queries, thus enhancing your application's efficiency.&lt;/p&gt;

&lt;p&gt;To illustrate, consider a scenario where you have a &lt;code&gt;Product&lt;/code&gt; model and your aim is to fetch the total count of reviews for each product. One inefficient approach would be to employ a loop to iterate through each product and retrieve the review count for each one.&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="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;reviews&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num_reviews&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reviews&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_list.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;products&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This approach will result in an N+1 query problem, where N is the number of products in the queryset. A more efficient way to do this is to use the &lt;code&gt;annotate()&lt;/code&gt; method to add an extra field to the queryset:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt;

&lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_reviews&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reviews&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_list.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;products&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, we are using the &lt;code&gt;Count()&lt;/code&gt; aggregation function to count the number of related reviews for each product. The &lt;code&gt;num_reviews&lt;/code&gt; field is added to the queryset as an annotation, and we can access it in the template.&lt;/p&gt;

&lt;p&gt;Using annotations can greatly improve the performance of your queries by reducing the number of database queries required. However, you should be careful when using them with large datasets, as they can increase the memory usage of your application. It's always a good practice to test the performance of your queries with realistic data and adjust them as necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Use aggregation:
&lt;/h3&gt;

&lt;p&gt;Aggregation is a powerful feature in Django that allows you to perform complex calculations on a set of values in the database. By using aggregation, you can minimize the number of queries needed to retrieve and process data, which can significantly improve performance.&lt;/p&gt;

&lt;p&gt;For example, let's say you have a model &lt;code&gt;Order&lt;/code&gt; with a field &lt;code&gt;price&lt;/code&gt;, and you want to calculate the total revenue for all orders. You can use the &lt;code&gt;aggregate()&lt;/code&gt; method to perform this calculation in a single query:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Sum&lt;/span&gt;

&lt;span class="n"&gt;total_revenue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;total&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;aggregate()&lt;/code&gt; method calculates the sum of the &lt;code&gt;price&lt;/code&gt; field for all &lt;code&gt;Order&lt;/code&gt; objects, and returns the result as a dictionary with the key &lt;code&gt;'total'&lt;/code&gt;. This code is much more efficient than manually iterating over all &lt;code&gt;Order&lt;/code&gt; objects and summing their prices, especially if there are a large number of orders in the database.&lt;/p&gt;

&lt;p&gt;Another example is calculating the average rating for a set of &lt;code&gt;Product&lt;/code&gt; objects. Here is the inefficient version that requires multiple queries:&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="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ratings_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ratings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ratings_sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ratings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;ratings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;average_rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ratings_sum&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code iterates over all &lt;code&gt;Product&lt;/code&gt; objects, and for each product, it queries the related &lt;code&gt;Rating&lt;/code&gt; objects and calculates the sum and count of their values. Finally, it calculates the average rating by dividing the sum by the count. This approach requires multiple queries and can be very slow if there are a large number of products and ratings.&lt;/p&gt;

&lt;p&gt;Here is the optimized version using aggregation:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Avg&lt;/span&gt;

&lt;span class="n"&gt;average_rating&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avg_rating&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ratings__value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;avg_rating&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;avg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this code, we use the &lt;code&gt;annotate()&lt;/code&gt; method to add an &lt;code&gt;avg_rating&lt;/code&gt; field to each &lt;code&gt;Product&lt;/code&gt; object, which is the average of the &lt;code&gt;value&lt;/code&gt; field of all related &lt;code&gt;Rating&lt;/code&gt; objects. Then, we use the &lt;code&gt;aggregate()&lt;/code&gt; method to calculate the average of the &lt;code&gt;avg_rating&lt;/code&gt; field for all &lt;code&gt;Product&lt;/code&gt; objects. This code only requires a single query and is much faster than the previous version.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Use caching:
&lt;/h3&gt;

&lt;p&gt;Caching allows you to store the results of a query in memory or on disk, so that subsequent requests can be served from the cache instead of making a database query. This can significantly improve the performance of your application.&lt;/p&gt;

&lt;p&gt;It is a powerful tool for query optimization as it allows you to avoid executing the same query repeatedly by storing the results in memory or on disk. By caching the results of a query, subsequent requests can be served faster without hitting the database, which can significantly improve the performance of your application.&lt;/p&gt;

&lt;p&gt;Here's an example of how caching can be used to improve query performance. Suppose you have a view that displays a list of products with their corresponding categories:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;product_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;products&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;product_list.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This view retrieves all products from the database and then loops through them to extract the set of categories. This can be inefficient if you have a large number of products.&lt;/p&gt;

&lt;p&gt;To optimize this query using caching, you can use Django's caching framework to store the set of categories in cache. Here's the updated view:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.core.cache&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;product_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;products&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;product_list.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this updated view, the categories are first retrieved from the cache using the &lt;code&gt;cache.get()&lt;/code&gt; function. If they are not found in the cache, they are computed and stored in cache using the &lt;code&gt;cache.set()&lt;/code&gt; function. Subsequent requests for the same view will retrieve the categories from cache instead of recomputing them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; that caching can also have drawbacks, such as increased memory usage and the need to keep the cache in sync with the database. It's important to use caching judiciously and only when it provides a measurable improvement in performance.&lt;/p&gt;

&lt;p&gt;Some pros of using caching include&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Faster response times: Caching can reduce the response times of web pages by storing frequently accessed data in memory or on disk, reducing the need to generate data from scratch each time a request is made.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability: Caching can help improve the scalability of web applications by reducing the load on the database and web server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced network traffic: By caching frequently accessed data, you can reduce the amount of data that needs to be transmitted over the network, resulting in faster load times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customizable caching policies: Django cache allows you to configure different caching policies for different types of data, giving you fine-grained control over how and when data is cached.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cons of using caching include&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Increased complexity: Adding caching to an application adds complexity, which can make it harder to maintain and debug.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Increased memory usage: Depending on the caching policy used, caching can result in increased memory usage, which can impact the performance of other applications running on the same server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cache invalidation: Caching introduces the problem of cache invalidation, which is the process of keeping the cache up-to-date with changes in the underlying data. In some cases, it may be difficult to ensure that the cache is always up-to-date, which can lead to inconsistent data being displayed to users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security risks: Caching sensitive data can introduce security risks if the cache is not properly secured.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Overall, caching can be an effective way to improve the performance of web applications, but it should be used judiciously and with care. It's important to weigh the potential benefits against the costs and risks before deciding to use caching in a production environment.&lt;/p&gt;

&lt;p&gt;For more information on how to set this up, there is a link to the official django docs in the reference section&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Use indexing:
&lt;/h3&gt;

&lt;p&gt;Indexing can improve the performance of your database queries by allowing the database to retrieve data more quickly. You can add indexes to your database tables using Django's migration framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Use database-level query optimization techniques:
&lt;/h3&gt;

&lt;p&gt;Depending on the database you are using, there may be specific query optimization techniques you can use to improve performance, such as optimizing the database schema, tuning database parameters, or using a different database engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Use third-party libraries:
&lt;/h3&gt;

&lt;p&gt;There are many third-party libraries available for Django that can help you optimize your database queries. For example, the django-debug-toolbar can be used to analyze the performance of your queries and identify areas for improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, writing faster queries is an essential part of optimizing a Django application's performance. This article highlights several best practices for writing efficient queries, such as using the select_related() and prefetch_related() methods, limiting the number of fields returned, and avoiding unnecessary database hits. The use of third-party packages like Django Debug Toolbar and Django Silk can also provide insight into query performance and help identify potential areas for optimization. By following these guidelines and regularly monitoring query performance, developers can ensure that their Django applications are performing as efficiently as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opensource.com/article/17/11/django-orm" rel="noopener noreferrer"&gt;Introduction to django-orm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.djangoproject.com/en/4.1/topics/db/optimization/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/topics/db/optimization/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.djangoproject.com/en/4.1/topics/db/queries/#querysets-are-lazy" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/topics/db/queries/#querysets-are-lazy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.djangoproject.com/en/4.1/ref/models/querysets/#when-querysets-are-evaluated" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/ref/models/querysets/#when-querysets-are-evaluated&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.djangoproject.com/en/4.1/topics/db/queries/#caching-and-querysets" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/topics/db/queries/#caching-and-querysets&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.1/topics/db/queries/#retrieving-a-single-object-with-get" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/topics/db/queries/#retrieving-a-single-object-with-get&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.1/topics/db/optimization/#use-queryset-select-related-and-prefetch-related" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/topics/db/optimization/#use-queryset-select-related-and-prefetch-related&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.djangoproject.com/en/4.1/topics/cache/#cache-key-prefixing" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/4.1/topics/cache/#cache-key-prefixing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>database</category>
      <category>performance</category>
    </item>
    <item>
      <title>JS vs TS: A Comprehensive Guide to Choosing the Right Programming Language</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Sun, 29 Jan 2023 21:32:01 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/js-vs-ts-a-comprehensive-guide-to-choosing-the-right-programming-language-577l</link>
      <guid>https://dev.to/joshthecodingaddict/js-vs-ts-a-comprehensive-guide-to-choosing-the-right-programming-language-577l</guid>
      <description>&lt;p&gt;In the world of web development, JavaScript and TypeScript are two of the most commonly used programming languages for creating dynamic web pages and web applications. JavaScript has a long-standing reputation among web developers, whereas TypeScript is a more recent addition to the scene that has gained popularity in recent years. &lt;/p&gt;

&lt;p&gt;Choosing the right language can be a difficult choice for developers due to the differences and similarities between the two. This article will delve into these differences, exploring topics such as type checking, classes, namespaces, and ES6 features. This article aims to give a comprehensive understanding of both JavaScript and TypeScript, allowing you to make an informed decision about which language is best for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is JavaScript?
&lt;/h2&gt;

&lt;p&gt;JavaScript, a widely utilized programming language, is renowned for its ability to create dynamic web pages and web applications. It was invented in the mid-1990s by Brendan Eich, while he was employed at Netscape Communications Corporation. JavaScript operates on the client-side, running in the user's browser rather than on the server, making it a crucial component in the development of interactive websites and applications.&lt;/p&gt;

&lt;p&gt;JavaScript is a versatile, object-oriented programming language used to build dynamic web pages and applications. It is a client-side language that executes in the user's browser and is capable of working with asynchronous code, making it well-suited for modern web development. JavaScript is loosely typed, meaning the data type of a variable can change during runtime, and it enables the creation of complex data structures. The language is supported by all major browsers, such as Chrome, Firefox, Edge, and Safari, and has widespread usage in front-end and server-side scripting through Node.js. With millions of developers relying on it, JavaScript is considered an essential tool in the world of web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is TypeScript?
&lt;/h2&gt;

&lt;p&gt;TypeScript is an object-oriented language that is statically typed, maintained by Microsoft, and compiled. It is a superset of JavaScript that strictly adheres to its syntax and adds additional features like optional type annotations, classes, interfaces, namespaces, and modules. This makes TypeScript a more efficient choice for complex, large-scale projects, compared to its dynamic and interpreted predecessor.&lt;/p&gt;

&lt;p&gt;TypeScript also includes features such as static typing, which helps to catch type-related errors at compile time rather than at runtime, and improved support for object-oriented programming, which makes it easier to write clean, maintainable, and scalable code.&lt;/p&gt;

&lt;p&gt;TypeScript compiles to JavaScript, which means that it can be executed in any environment that supports JavaScript, such as a browser or a server. As a result, TypeScript has become a popular choice for building complex web applications and large-scale software systems, and it is supported by many popular libraries and frameworks, such as Angular, React, and Vue.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript vs TypeScript
&lt;/h2&gt;

&lt;p&gt;JavaScript (JS) and TypeScript (TS) are both programming languages used for web development, but they have some key differences:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Type Checking:
&lt;/h3&gt;

&lt;p&gt;Type checking is a process of verifying the type of a variable or an expression at runtime to ensure that it meets the expected type. Type checking is important because it can help to catch type-related errors before they cause unexpected behavior in your code.&lt;/p&gt;

&lt;p&gt;In JavaScript, type verification is done dynamically, allowing for variables to change their type during runtime. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&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;In this example, the variable &lt;code&gt;x&lt;/code&gt; is initially assigned the value &lt;code&gt;42&lt;/code&gt;, which is a number. However, it is then reassigned the value &lt;code&gt;"Hello"&lt;/code&gt;, which is a string. This is possible in JavaScript because it is a dynamically typed language, and the type of a variable can change dynamically during runtime.&lt;/p&gt;

&lt;p&gt;On the other hand, TypeScript has static type checking, which means that the type of a variable must be specified at compile time and cannot change dynamically during runtime. For example:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Type '"Hello"' is not assignable to type 'number'.&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. ES6 Features:
&lt;/h3&gt;

&lt;p&gt;ECMAScript 6 (ES6), also known as ECMAScript 2015, is a version of JavaScript that introduced several new features and syntax improvements. These features are designed to make JavaScript more expressive, readable, and maintainable, and have been widely adopted by developers.&lt;/p&gt;

&lt;p&gt;Both JavaScript and TypeScript support most of the ES6 features, including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Arrow functions: A shorthand syntax for writing anonymous functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Template literals: A way to embed expressions into strings using the backtick (&lt;code&gt;`&lt;/code&gt;) character.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Destructuring: A way to extract data from arrays and objects into separate variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modules: A way to organize code into reusable and manageable pieces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Classes: A way to define object-oriented classes in JavaScript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promises: A way to handle asynchronous code and error handling.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, TypeScript provides additional features and syntax that are not available in JavaScript, including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Type annotations: A way to specify the type of a variable, function, or expression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interfaces: A way to define a blueprint for an object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generics: A way to write reusable functions and classes that can work with any type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decorators: A way to add metadata to a class, method, or property.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both JavaScript and TypeScript support most of the ES6 features, but TypeScript provides additional features and syntax that are not available in JavaScript, making it a more powerful and expressive language for building large and complex applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Classes:
&lt;/h3&gt;

&lt;p&gt;Classes are a fundamental concept in object-oriented programming (OOP) that provide a blueprint for creating objects and encapsulating data and behavior.&lt;/p&gt;

&lt;p&gt;JavaScript has a prototype-based model for creating objects, and it does not have a built-in class syntax. However, classes can be simulated in JavaScript using prototypes and functions. For example:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getFullName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// "John Doe"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;Person&lt;/code&gt; function acts as a constructor for creating objects, and the &lt;code&gt;getFullName&lt;/code&gt; method is added to the prototype of the &lt;code&gt;Person&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;On the other hand, TypeScript has a class syntax that provides a more familiar and convenient way of defining objects and encapsulating data and behavior. For example:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getFullName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// "John Doe"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;Person&lt;/code&gt; class is defined using the &lt;code&gt;class&lt;/code&gt; syntax, and it has a constructor and a method. The class syntax provides a more intuitive and familiar way of defining objects and encapsulating data and behavior compared to the prototype-based model in JavaScript.&lt;/p&gt;

&lt;p&gt;In conclusion, TypeScript provides a class syntax that provides a more intuitive and convenient way of defining objects and encapsulating data and behavior compared to the prototype-based model in JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Namespaces:
&lt;/h3&gt;

&lt;p&gt;Namespaces are a way of organizing and grouping related code together. TypeScript supports namespaces, which are used to organize code into logical groups and prevent naming collisions, whereas in JavaScript you have to use modules for this purpose. In JavaScript, namespaces can be achieved by using objects and nested objects. For example:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;MyNamespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;MyNamespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Utils&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyNamespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;MyNamespace&lt;/code&gt; object acts as a namespace, and the &lt;code&gt;Utils&lt;/code&gt; object contains the related utility functions.&lt;/p&gt;

&lt;p&gt;On the other hand, TypeScript provides a &lt;code&gt;namespace&lt;/code&gt; keyword that provides a more intuitive and convenient way of organizing and grouping related code together. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;MyNamespace&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyNamespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the &lt;code&gt;MyNamespace&lt;/code&gt; namespace is defined using the &lt;code&gt;namespace&lt;/code&gt; keyword, and the related functions are exported using the &lt;code&gt;export&lt;/code&gt; keyword. The &lt;code&gt;namespace&lt;/code&gt; keyword provides a more intuitive and convenient way of organizing and grouping related code together compared to using objects in JavaScript.&lt;/p&gt;

&lt;p&gt;In conclusion, TypeScript provides the &lt;code&gt;namespace&lt;/code&gt; keyword that provides a more intuitive and convenient way of organizing and grouping related code together compared to using objects in JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Compilation:
&lt;/h3&gt;

&lt;p&gt;The process of transforming a high-level programming language into machine-readable code is called Compilation. Unlike TypeScript, which is a statically typed language and requires the use of a compiler, JavaScript is dynamically typed and does not need to be compiled before it is executed. This means that JavaScript code can be written and tested on the fly, making it ideal for rapid prototyping.&lt;/p&gt;

&lt;p&gt;On the other hand, TypeScript's static typing allows the compiler to catch type-related errors before execution, leading to a more efficient and error-free development process. The TypeScript code is written and then compiled into JavaScript, which can then be executed by the browser or Node.js runtime. This ensures that the generated JavaScript code is of high quality and free from type-related errors.&lt;/p&gt;

&lt;p&gt;The following is an example of TypeScript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Hello, John!"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And this is the equivalent JavaScript code generated by the TypeScript compiler:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;!&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "Hello, John!"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In conclusion, TypeScript requires compilation, which allows the TypeScript compiler to perform type-checking and catch type-related errors before the code is executed. This makes the development process more efficient and less error-prone compared to JavaScript, which is executed directly without the need for compilation.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Type Annotations:
&lt;/h3&gt;

&lt;p&gt;Type annotations in programming languages specify the expected type of a variable or expression.&lt;/p&gt;

&lt;p&gt;In JavaScript, there is no built-in syntax for type annotations, and type information is not available at compile time. For example:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the type of the variable &lt;code&gt;x&lt;/code&gt; is inferred to be a number by the value that it is assigned. However, there is no explicit type information available in the code.&lt;/p&gt;

&lt;p&gt;On the other hand, TypeScript provides optional type annotations, which allow developers to specify the expected type of a variable or expression explicitly. For example:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In this example, the type of the variable &lt;code&gt;x&lt;/code&gt; is explicitly specified as a &lt;code&gt;number&lt;/code&gt; using the colon &lt;code&gt;:&lt;/code&gt; syntax. This information is available at compile time, and TypeScript can use it to perform static type checking, catch type-related errors, and provide better tooling and code analysis.&lt;/p&gt;

&lt;p&gt;TypeScript type annotations are optional, but they are highly recommended for large-scale applications because they can improve the quality and maintainability of the code. The type annotations can be inferred from the values that are assigned to the variables, or they can be specified explicitly by the developer.&lt;/p&gt;

&lt;p&gt;In conclusion, TypeScript provides optional type annotations, which can improve the quality, maintainability, and safety of the code, while JavaScript does not have built-in syntax for type annotations.&lt;/p&gt;

&lt;p&gt;In summary, TypeScript adds optional static typing, classes, and other features to JavaScript, making it a more suitable choice for larger and more complex projects, while JavaScript is still widely used due to its ease of use and compatibility with older browsers.&lt;/p&gt;

</description>
      <category>postmarkchallenge</category>
      <category>career</category>
      <category>help</category>
      <category>discuss</category>
    </item>
    <item>
      <title>What is API Latency</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Sat, 31 Dec 2022 21:49:32 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/what-is-api-latency-4m4f</link>
      <guid>https://dev.to/joshthecodingaddict/what-is-api-latency-4m4f</guid>
      <description>&lt;h2&gt;
  
  
  What is API latency?
&lt;/h2&gt;

&lt;p&gt;Latency in an API refers to the time it takes for a user's query to be processed and for a response to be returned. A lower latency means a faster response time and a better user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the response rate?
&lt;/h2&gt;

&lt;p&gt;Response rate measures the total time it takes for a server to fulfill a request, including the API latency, or the time it takes for information to be transmitted from the server to the requesting party. It is important to optimize response rate to improve the overall user experience. Latency is a component of response rate but is not the only factor that contributes to the response time measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is server response time?
&lt;/h2&gt;

&lt;p&gt;Response time refers to the amount of time it takes for the server to process a request and send back a response to the client. A shorter response time can lead to a better user experience and can be a key factor in the performance and efficiency of an API. It is important to monitor and optimize server response time to ensure that the API is functioning effectively and efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a good server response time?
&lt;/h3&gt;

&lt;p&gt;Typically anything less than 300ms would put you in the best 20% of sites, and &lt;strong&gt;less than 200ms would put you in the best 10%&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;source&lt;/em&gt;&lt;a href="https://www.littledata.io/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a bad server response time?
&lt;/h3&gt;

&lt;p&gt;Server response time of more than 830ms would put you in the worst 20% of sites, and &lt;strong&gt;more than 1.1 seconds would put you in the worst-performing sites&lt;/strong&gt;.&lt;br&gt;
&lt;em&gt;source&lt;/em&gt;&lt;a href="https://www.littledata.io/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of APIs latency rate vs response rate
&lt;/h2&gt;

&lt;p&gt;The time it takes for a request to be fulfilled by an API server, including the time it takes for the requested information to be transmitted, is known as the response rate. The API latency rate refers specifically to the time it takes for the requested information to be transmitted from the server to the requesting party.&lt;/p&gt;

&lt;h2&gt;
  
  
  What causes high latency?
&lt;/h2&gt;

&lt;p&gt;The speed at which a server responds to a request for information through an API can be affected by a variety of factors, such as the server's capacity and processing power, the number of requests being made at a given time, and the efficiency with which those requests are managed. High latency rates, or slow response times, can negatively impact user satisfaction and may be caused by server overload, a bottleneck of requests, or other issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can the latency of an API be monitored?
&lt;/h2&gt;

&lt;p&gt;There are various methods for monitoring the latency of an API, such as a ping test or using web service HTTP/HTTPS monitors. These tools can provide information about API latency, response times, loading times, and other relevant metrics to help understand the user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some ways to reduce latency
&lt;/h2&gt;

&lt;p&gt;These include optimizing server hardware and capacity, using efficient algorithms and data structures, minimizing the distance between the server and the requesting party, and minimizing the amount of data sent over the network.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Integrating Paystack payments in Django website</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Fri, 21 Oct 2022 20:57:11 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/integrating-paystack-payments-in-django-website-1i1l</link>
      <guid>https://dev.to/joshthecodingaddict/integrating-paystack-payments-in-django-website-1i1l</guid>
      <description>&lt;p&gt;&lt;strong&gt;TABLE OF CONTENTS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Introduction
&lt;/li&gt;
&lt;li&gt;  Prerequisites
&lt;/li&gt;
&lt;li&gt;  Project Setup
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dev.tocreating-models"&gt;Creating models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  User registration and login
&lt;/li&gt;
&lt;li&gt;  Implementing deposit view
&lt;/li&gt;
&lt;li&gt;  Conclusion
&lt;/li&gt;
&lt;li&gt;  Reference
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://paystack.com/" rel="noopener noreferrer"&gt;Paystack&lt;/a&gt; is a payment gateway that helps individuals and businesses in Africa to accept payments from anywhere in the world. In this guide, I will be showing you how to use Paystack as a third-party API to facilitate payments in your Django website. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow through with this guide you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; A good understanding of Python&lt;/li&gt;
&lt;li&gt; Basic understanding of Django&lt;/li&gt;
&lt;li&gt; Basic understanding of Html&lt;/li&gt;
&lt;li&gt; Usage of the  &lt;a href="https://docs.python-requests.org/en/latest/" rel="noopener noreferrer"&gt;Python request&lt;/a&gt;  library&lt;/li&gt;
&lt;li&gt; A Paystack account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's dive into the guide, all codes can be found on Github in this  &lt;a href="https://github.com/skynette/paystack-django-integration" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Create a folder, start a virtual environment and start basic project&lt;/strong&gt;&lt;br&gt;
create a virtual environment using &lt;code&gt;virtualenv env&lt;/code&gt;&lt;br&gt;
activate the virtual environment &lt;code&gt;using source env/Scripts/activate&lt;/code&gt;&lt;br&gt;
install django using &lt;code&gt;pip install django&lt;/code&gt; this will install the latest version of django, however I am going to use version 3.0 in this guide, to install that do &lt;code&gt;pip install django==3.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a project and install apps&lt;/strong&gt;&lt;br&gt;
Now start the project using &lt;code&gt;django-admin startproject zcore .&lt;/code&gt;&lt;br&gt;
zcore is the name of the project and dot is used to start the project in the current directory.&lt;br&gt;
Next step is two create two apps, one for authentication and another to handle all payments related code&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python manage.py startapp accounts
python manage.py startapp payments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F656o76yyofjt2stcwvyg.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%2F656o76yyofjt2stcwvyg.png" alt="project setup 1"&gt;&lt;/a&gt;&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%2F90btw7pbspv0lz5zvqta.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%2F90btw7pbspv0lz5zvqta.png" alt="project setup 2"&gt;&lt;/a&gt;&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%2F28nv82z3g1pezpzf9mom.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%2F28nv82z3g1pezpzf9mom.png" alt="project setup 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the newly installed apps in &lt;code&gt;settings.py&lt;/code&gt;&lt;br&gt;
Also add paystack secret and public keys in &lt;code&gt;settings.py&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="n"&gt;PAYSTACK_SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
&lt;span class="n"&gt;PAYSTACK_PUBLIC_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;where to find them on paystack&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%2Fk11ko9qb5u7p878vb0da.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%2Fk11ko9qb5u7p878vb0da.png" alt="keys on paystack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate into both folders created and add a new file called &lt;code&gt;urls.py&lt;/code&gt; and add the following code&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

&lt;span class="p"&gt;]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Include these urls in main url file &lt;code&gt;zcore.urls&lt;/code&gt; &lt;br&gt;
Your file should look like this&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt;  &lt;span class="n"&gt;django.contrib&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;  &lt;span class="n"&gt;django.urls&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;admin/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;accounts/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;accounts.urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;payments/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payments.urls&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating models
&lt;/h2&gt;

&lt;p&gt;Next step is to create a wallet model to keep track of funds deposited by a user and a payment model to describe what a payment is.&lt;br&gt;
In &lt;code&gt;payments.model&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.paystack&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;Paystack&lt;/span&gt;

&lt;span class="c1"&gt;# Create your models here.
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserWallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;OneToOneField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NGN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PositiveIntegerField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BooleanField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;date_created&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ordering&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;-date_created&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Payment: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;token_urlsafe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;object_with_similar_ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;object_with_similar_ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;

        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;We will need another helper class to handle payment verification, so in the payments folder create a file called &lt;code&gt;paystack.py&lt;/code&gt;&lt;br&gt;
paste this block of code in the file&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Paystack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;PAYSTACK_SK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PAYSTACK_SECRET_KEY&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.paystack.co/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transaction/verify/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PAYSTACK_SK&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;response_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;response_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;response_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;response_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;you will need to install requests for this so do a quick &lt;code&gt;pip install requests&lt;/code&gt;&lt;br&gt;
with that we can now add a verify payment property on our payment model&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;def&lt;/span&gt; &lt;span class="nf"&gt;amount_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;paystack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Paystack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paystack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  User registration and login
&lt;/h2&gt;

&lt;p&gt;For the registration and login, I will be doing something very simple as it is not the focus of this guide.&lt;br&gt;
Paste the code in &lt;code&gt;accounts.views&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;payments.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserWallet&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;authenticate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;login_required&lt;/span&gt;

&lt;span class="c1"&gt;# Create your views here.
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;UserWallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;register.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;login_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;    
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;password&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;initiate_payment&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;login&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;login.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@login_required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;logout_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;login&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;Add the corresponding url paths for the views in &lt;code&gt;urls.py&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt;  &lt;span class="n"&gt;django.urls&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;register/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;register&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;login/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login_view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;logout/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logout_view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;logout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We will use dummy login and register page from bootstrap, file can be found in the &lt;a href="https://github.com/skynette/paystack-django-integration" rel="noopener noreferrer"&gt;github repo&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;Setup templates dirs by adding &lt;code&gt;'DIRS': [os.path.join(BASE_DIR, 'templates')]&lt;/code&gt; in &lt;code&gt;settings.py&lt;/code&gt;&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%2Fb4hvfsecigztpzqfain8.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%2Fb4hvfsecigztpzqfain8.png" alt="template dirs settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point you can run &lt;code&gt;python manage.py runserver&lt;/code&gt; and navigate to &lt;code&gt;127.0.0.1:8000/accounts/register&lt;/code&gt; in your browser window to see the registration 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%2Fin32zu0ob3dzeub9sdhy.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%2Fin32zu0ob3dzeub9sdhy.png" alt="register page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see some warnings, to get rid of them makemigrations and migrate using;&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;Create a superuser so that we can login to django admin via &lt;code&gt;127.0.0.1:8000/admin&lt;/code&gt; to see all the magic happening.&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%2Fj1vpidpbo0qi2mg1bavc.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%2Fj1vpidpbo0qi2mg1bavc.png" alt="migrations"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;To see all payment objects in admin area register the payments model in &lt;code&gt;payments.admin&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt;  &lt;span class="n"&gt;django.contrib&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt;  &lt;span class="kn"&gt;import&lt;/span&gt;  &lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserWallet&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;PaymentAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;list_display&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ref&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verified&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date_created&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PaymentAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserWallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Implementing deposit view
&lt;/h2&gt;

&lt;p&gt;Create two views, one to initiate the payment and another to verify payments. &lt;br&gt;
In &lt;code&gt;payments.views&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserWallet&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initiate_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;pk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PAYSTACK_PUBLIC_KEY&lt;/span&gt;

        &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;field_values&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;paystack_pub_key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;amount_value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;amount_value&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;make_payment.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;payment.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;verified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_payment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;verified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;user_wallet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UserWallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;user_wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;
        &lt;span class="n"&gt;user_wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; funded wallet successfully&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;payment.urls&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;initiate-payment/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;initiate_payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;initiate_payment&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;verify-payment/&amp;lt;str:ref&amp;gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verify_payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;verify_payment&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;



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

&lt;/div&gt;

&lt;p&gt;The process flow goes like this;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User inputs an amount to fund his wallet&lt;/li&gt;
&lt;li&gt;Clicks on pay then it takes them to page that displays the payment details&lt;/li&gt;
&lt;li&gt;Then proceeds to pay by clicking the pay button, this will open a payment modal handled by paystack, when the process is complete paystack will send a request to the &lt;code&gt;callback URL&lt;/code&gt; which we set up  to confirm the details of the transaction.&lt;/li&gt;
&lt;/ul&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%2Fx0ws3ec3pxov4y11jx79.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%2Fx0ws3ec3pxov4y11jx79.png" alt="payment flow 1"&gt;&lt;/a&gt;&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%2Fnszvsc7vwedr10ggdtzg.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%2Fnszvsc7vwedr10ggdtzg.png" alt="payment flow 2"&gt;&lt;/a&gt;&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%2Fc4fv75massei1n4b3bkn.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%2Fc4fv75massei1n4b3bkn.png" alt="payment flow 3"&gt;&lt;/a&gt;&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%2F6d0q5z38sjyd95mcps23.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%2F6d0q5z38sjyd95mcps23.png" alt="payment flow 4"&gt;&lt;/a&gt;&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%2Fznger2hro0glilk30kip.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%2Fznger2hro0glilk30kip.png" alt="payment flow 5"&gt;&lt;/a&gt;&lt;br&gt;
Code for the payment pages can be found in the &lt;a href="https://github.com/skynette/paystack-django-integration" rel="noopener noreferrer"&gt;repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have successfully integrated Paystack into our Django application and deposited an amount successfully.&lt;/p&gt;

&lt;p&gt;All codes can be found in this &lt;a href="https://github.com/skynette/paystack-django-integration" rel="noopener noreferrer"&gt;repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://paystack.com/docs/" rel="noopener noreferrer"&gt;Paystack docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect with me on  &lt;a href="https://twitter.com/cut3josh" rel="noopener noreferrer"&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt;  |  &lt;a href="https://github.com/skynette/" rel="noopener noreferrer"&gt;&lt;strong&gt;Github&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
I hope this was helpful&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>django</category>
      <category>tutorial</category>
      <category>python</category>
      <category>api</category>
    </item>
    <item>
      <title>Use custom python scripts from any directory in windows</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Thu, 19 May 2022 18:12:10 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/use-custom-python-scripts-from-any-directory-in-windows-2376</link>
      <guid>https://dev.to/joshthecodingaddict/use-custom-python-scripts-from-any-directory-in-windows-2376</guid>
      <description>&lt;p&gt;In this one I am going to be showing you how you can run your python scripts from the terminal in directory on windows.&lt;/p&gt;

&lt;p&gt;But first we shall look at what a PATH variable means and what ENVIRONMENTAL variables mean&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environmental Variable&lt;/strong&gt;&lt;br&gt;
An &lt;em&gt;environment variable&lt;/em&gt; is a variable whose value is set outside the program, typically through functionality built into the operating system or microservice. An environment variable is made up of a name/value pair, and any number may be created and available for reference at a point in time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PATH Variable&lt;/strong&gt;&lt;br&gt;
The &lt;em&gt;PATH variable&lt;/em&gt; is an environment variable that contains an ordered list of paths that Linux will search for executables when running a command. Using these paths means that we do not have to specify an absolute path when running a command.&lt;/p&gt;

&lt;p&gt;Now that we know what these terms mean we can get into the actual work&lt;br&gt;
First step is to write our custom script, in this case I am using a script I developed to kill annoying tasks because task manager sometimes does not respond&lt;br&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%2Fz6jrqc19d2gq0lkajsqs.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%2Fz6jrqc19d2gq0lkajsqs.png" alt="Code snippet"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[!] Usage: kill.py &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;program name&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;program&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[*] Killing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;taskkill -f -im &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;program&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.exe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Next step is to create a folder for our custom scripts and add the folder path to environmental variables&lt;br&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%2Fqqjpjdekxqc8we9bmd21.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%2Fqqjpjdekxqc8we9bmd21.png" alt="create folder"&gt;&lt;/a&gt;&lt;br&gt;
After copying folder path click windows button and&lt;br&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%2F4iy7q3psoeldfmn9dprb.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%2F4iy7q3psoeldfmn9dprb.png" alt="next step"&gt;&lt;/a&gt;&lt;br&gt;
Next step click on environmental variables&lt;br&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%2Fdbkle3jbq9lwtmal905g.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%2Fdbkle3jbq9lwtmal905g.png" alt="click on env varibles"&gt;&lt;/a&gt;&lt;br&gt;
click on path and then edit at the bottom&lt;br&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%2F78v985mf73flaamaxvd9.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%2F78v985mf73flaamaxvd9.png" alt="click on path and edit"&gt;&lt;/a&gt;&lt;br&gt;
click on new and then paste in the path to our custom folder&lt;br&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%2Flos95f3bj25oob1dzrvg.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%2Flos95f3bj25oob1dzrvg.png" alt="paste path"&gt;&lt;/a&gt;&lt;br&gt;
And voila we are ready to go. So to test this we open a new terminal and type out the name of our script in this case &lt;code&gt;kill.py&lt;/code&gt; you should see the error output&lt;br&gt;
Anyways we go ahead and test this&lt;br&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%2F1bmv7p8r5wyyqhx3lp87.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%2F1bmv7p8r5wyyqhx3lp87.png" alt="code results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use this to automate your boring tasks, Happy Coding Everyone :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Making a fancy number guessing game</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Sun, 17 Apr 2022 00:59:52 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/making-a-fancy-number-guessing-game-2f4</link>
      <guid>https://dev.to/joshthecodingaddict/making-a-fancy-number-guessing-game-2f4</guid>
      <description>&lt;p&gt;&lt;strong&gt;This article is tailored towards new and inexperienced coders that want to start their coding careers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Demo of what we will be coding&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%2Fuploads%2Farticles%2F0ppj4ly5n9si3sc6bib2.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%2F0ppj4ly5n9si3sc6bib2.png" alt="Guessing game test" width="648" height="942"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Users\Josh\Desktop&amp;gt;guessing.py
Enter player name: JoshTheCodingAddict

Hi JoshTheCodingAddict Welcome to my fancy number guessing game
=====================
| enter 10---Easy   |
| enter 20---Medium |
| enter 30---Hard   |
=====================

[*] Select difficulty level: 10
[*] You have 3 number of guesses left!
[!] Guess the lucky number: 9
[-] Sorry please try again

[*] You have 2 number of guesses left!
[!] Guess the lucky number: 8
[-] Sorry please try again

[*] You have 1 number of guesses left!
[!] Guess the lucky number: 7
[-] Sorry please try again

[!] Game over, type c to retry and q to quit game: c
[*] You have 3 number of guesses left!
[!] Guess the lucky number: 7
[-] Sorry please try again

[*] You have 2 number of guesses left!
[!] Guess the lucky number: 6
[-] Sorry please try again

[*] You have 1 number of guesses left!
[!] Guess the lucky number: 5
[-] Sorry please try again

[!] Game over, type c to retry and q to quit game: 4
[-] Wrong input
[!] Game over, type c to retry and q to quit game: c
[*] You have 3 number of guesses left!
[!] Guess the lucky number: 3
[-] Sorry please try again

[*] You have 2 number of guesses left!
[!] Guess the lucky number: 2
[+] Congratulations!! you won the game

[!] Thanks for playing!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Game requirements:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Player name&lt;/li&gt;
&lt;li&gt;Game levels: Easy, Intermediate, Hard&lt;/li&gt;
&lt;li&gt;Number of guesses: how many wrong guesses before ending the game&lt;/li&gt;
&lt;li&gt;Fancy Instructions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lets dive into it&lt;/p&gt;

&lt;h2&gt;
  
  
  Game logic
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Users are presented a welcome message and asked to select the game difficulty&lt;/li&gt;
&lt;li&gt;Then game starts and player has n number of chances to guess the lucky number&lt;/li&gt;
&lt;li&gt;If the correct is number is inputed, player is presented with a congratulations message&lt;/li&gt;
&lt;li&gt;If player runs out of guesses then player is presented with a message telling them they failed to guess the correct number and should retry or exit the game.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without further ado lets get our hands dirty and write some code&lt;/p&gt;

&lt;h2&gt;
  
  
  Modules used:
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;random&lt;/code&gt; - used to generate pseudo random numbers&lt;/p&gt;

&lt;p&gt;So we start by importing random&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then setting our variables: player name, welcome message, congratulations message, failed message, difficulty level, lucky_number and number of guesses&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;player_name = input("Enter player name: ")
welcome_message = f"""
Hi {player_name} Welcome to my fancy number guessing game
=====================
| enter 10---Easy   |
| enter 20---Medium |
| enter 30---Hard   |
=====================
"""
print(welcome_message)
congratulations_message = "[+] Congratulations!! you won the game\n"
failed_message = "[-] Sorry please try again\n"
difficulty = int(input("[*] Select difficulty level: "))
lucky_number = random.randint(1, difficulty)
guesses = 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now start the game loop and write the logic for guessing and comparing guesses&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while guesses &amp;gt;= 0:
    if guesses == 0:
        retry = input("[!] Game over, type c to retry and q to quit game: ")
        if retry == "c": guesses = 3
        elif retry == "q": break
        else: print("[-] Wrong input")
    else:  
        print(f"[*] You have {guesses} number of guesses left!")
        guessed = int(input("[!] Guess the lucky number: "))
        if guessed == lucky_number:
            print(congratulations_message)
            break
        else:
            print(failed_message)
            guesses = guesses - 1

print("[!] Thanks for playing!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full code below
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import random
player_name = input("Enter player name: ")
welcome_message = f"""
Hi {player_name} Welcome to my fancy number guessing game
=====================
| enter 10---Easy   |
| enter 20---Medium |
| enter 30---Hard   |
=====================
"""
print(welcome_message)
congratulations_message = "[+] Congratulations!! you won the game\n"
failed_message = "[-] Sorry please try again\n"
difficulty = int(input("[*] Select difficulty level: "))
lucky_number = random.randint(1, difficulty)
guesses = 3
while guesses &amp;gt;= 0:
    if guesses == 0:
        retry = input("[!] Game over, type c to retry and q to quit game: ")
        if retry == "c": guesses = 3
        elif retry == "q": break
        else: print("[-] Wrong input")
    else:  
        print(f"[*] You have {guesses} number of guesses left!")
        guessed = int(input("[!] Guess the lucky number: "))
        if guessed == lucky_number:
            print(congratulations_message)
            break
        else:
            print(failed_message)
            guesses = guesses - 1

print("[!] Thanks for playing!")

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

&lt;/div&gt;



&lt;p&gt;Feel free to improve on this and Happy Coding :)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Leetcode Problem: Construct the Rectangle</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Wed, 13 Apr 2022 14:59:55 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/leetcode-problem-construct-the-rectangle-5fen</link>
      <guid>https://dev.to/joshthecodingaddict/leetcode-problem-construct-the-rectangle-5fen</guid>
      <description>&lt;p&gt;In this article I would be going over a solution to leetcode problem &lt;a href="https://leetcode.com/problems/construct-the-rectangle/" rel="noopener noreferrer"&gt;492: Construct the Rectangle&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Two solutions were developed and I will be walking you through them&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutuion 1
&lt;/h2&gt;

&lt;p&gt;The function accepts a parameter area, in this example we would go with 16&lt;br&gt;
&lt;code&gt;area = 16&lt;/code&gt;&lt;br&gt;
Next we create our answer dictionary variable to hold the factors of the target area&lt;br&gt;
&lt;code&gt;ad = {}&lt;/code&gt;&lt;br&gt;
Also setup a temp list with maximum and minimum values of infinity&lt;br&gt;
&lt;code&gt;temp = [ float('inf'),  float('-inf')]&lt;/code&gt;&lt;br&gt;
First we wanna iterate over from 1 till the square root of the target area + 1 to avoid duplicates&lt;br&gt;
&lt;code&gt;for 1,2...sqrt(16)+1 --&amp;gt; 5&lt;/code&gt;&lt;br&gt;
For every iteration, if we find a factor of that number then we want to save it to the answer dictionary&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; # 16/1
 # 16/2
 # 16/3
 # 16/4
 ad = {'1':'16', '2':'8', '4':'4'}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can iterate through the answer dictionary to select the best length and width combination with the lowest absolute difference&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; for k,v in ad:
    if abs(k-v) &amp;lt; abs(temp[0]-temp[1])
    temp[0], temp[1] = min(k, v), max(k,v)
    return temp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end of this process we have the answer in temp list&lt;/p&gt;

&lt;p&gt;Code Below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import math
class Solution:
    def constructRectangle(self, area: int) -&amp;gt; List[int]:
        answer_dict = {}
        temp = [float('inf'),  float('-inf')]
        for n in range(1, int(math.sqrt(area))+1):
            if area%n == 0:
                answer_dict[n] = area // n
        for k, v in answer_dict.items():
            if abs(temp[0] - temp[1]) &amp;gt; abs(k-v):
                temp[0], temp[1] = max(k, v), min(k, v)
        return temp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first solution was long and it could be made a lot simpler&lt;br&gt;
This second solution makes use of one list to keep the prospective lengths and breadths&lt;br&gt;
Easy to understand&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def constructRectangle(self, area: int) -&amp;gt; List[int]:
        ans = []
        for i in range(1, int(sqrt(area))+1):
            j = area // i
            if i * j == area:
                if i &amp;lt;= j:
                    ans.append([max(i,j), min(i,j)])
        return ans[-1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A little task for the readers, what is the time and space complexities of both solutions&lt;br&gt;
Also do let me know if you have a better solution, or any improvements to be made&lt;/p&gt;

&lt;p&gt;Happy Cocding :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>challenge</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>Understanding Command Line Arguments by making a simple file searcher</title>
      <dc:creator>Joshua Hassan</dc:creator>
      <pubDate>Tue, 12 Apr 2022 01:38:52 +0000</pubDate>
      <link>https://dev.to/joshthecodingaddict/understanding-command-line-arguments-by-making-a-simple-file-searcher-2ao8</link>
      <guid>https://dev.to/joshthecodingaddict/understanding-command-line-arguments-by-making-a-simple-file-searcher-2ao8</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;The&lt;/strong&gt; sys.argv &lt;strong&gt;Array&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are various ways of handling Python command line arguments, but what you need to know is that the underlying support for all Python command line arguments is provided by sys.argv.&lt;/p&gt;

&lt;p&gt;The examples will show you how to handle the python command line arguments stored in sys.argv and to solve a few problems that come when trying to access them.&lt;/p&gt;

&lt;p&gt;We will learn how to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access&lt;/strong&gt; the contents of sys.argv&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process&lt;/strong&gt; whitespaces in python command line arguments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle&lt;/strong&gt; &lt;strong&gt;errors&lt;/strong&gt; while processing python command line arguments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Displaying Arguments&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The sys module exposes an array named argv that includes the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;argv[0]&lt;/strong&gt; contains the name of the current Python program.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;argv[1:]&lt;/strong&gt;, the rest of the list, contains any and all Python command line arguments passed to the program.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;for example&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%2Ful60klmvxb5rozo6p5of.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%2Ful60klmvxb5rozo6p5of.png" alt="Code sample showing sys.argv"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Line 1&lt;/strong&gt; imports the python module &lt;code&gt;sys&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Line 3&lt;/strong&gt; gives the name of the program by getting the first item in the list &lt;code&gt;sys.argv&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Line 5&lt;/strong&gt; displays the python command line arguments by getting all the remaining items of the list &lt;code&gt;sys.argv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Running the script above with a list of arguments as shown&lt;/p&gt;

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

python argv.py cat dog sheep friends eleven
Name of script:                argv.py
Arguments passed to script:    ['cat', 'dog', 'sheep', 'friends', 'eleven']


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

&lt;/div&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%2F0vycrjbqj1l1qu0yjgbk.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%2F0vycrjbqj1l1qu0yjgbk.png" alt="Code sample showing output"&gt;&lt;/a&gt;&lt;br&gt;
The output confirms that the content of &lt;code&gt;sys.argv[0]&lt;/code&gt; is the Python script &lt;code&gt;argv.py&lt;/code&gt;, and that the remaining elements of the sys.argv list contains the arguments of the script, &lt;code&gt;['cat', 'dog', 'sheep', 'friends', 'eleven']&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Escaping Whitespace Characters&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;On Linux, whitespaces can be escaped by doing one of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Surrounding&lt;/strong&gt; the arguments with single quotes (')&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surrounding&lt;/strong&gt; the arguments with double quotes (")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefixing&lt;/strong&gt; each space with a backslash ()
Without one of these solutions, the script will store two arguments instead of one as in the example below&lt;/li&gt;
&lt;/ol&gt;

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

C:\Users\UserName\Desktop\DevPosts&amp;gt;python argv.py "cat dog"
Name of script:                argv.py
Arguments passed to script:    ['cat dog']

C:\Users\UserName\Desktop\DevPosts&amp;gt;python argv.py cat dog
Name of script:                argv.py
Arguments passed to script:    ['cat', 'dog']


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

&lt;/div&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%2Fxnymjnsyn8rnka61kkc2.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%2Fxnymjnsyn8rnka61kkc2.png" alt="Code smaple showing output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Handling Errors&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Many things can go wrong, so it’s a good idea to provide the users of your program with some guidance in the event they pass incorrect arguments at the command line. For example, kill.py expects one argument, and if you omit it, then you get an error:&lt;/p&gt;

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

Traceback (most recent call last):
  File "C:\Users\UserName\Desktop\DevPosts\searcher.py", line 4, in &amp;lt;module&amp;gt;
    print("File To Search:                {}".format(sys.argv[1]))
IndexError: list index out of range


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

&lt;/div&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%2Flj3oj92l7ab2l3p40ft8.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%2Flj3oj92l7ab2l3p40ft8.png" alt="Code sample showing output 4"&gt;&lt;/a&gt;&lt;br&gt;
The Python exception &lt;code&gt;IndexError&lt;/code&gt;is raised, and the corresponding traceback shows that the error is caused by the expression &lt;code&gt;arg = sys.argv[1]&lt;/code&gt;. The message of the exception is list index out of range. So you didn’t pass an argument at the command line, so there’s nothing in the list &lt;code&gt;sys.argv&lt;/code&gt; at index 1.&lt;/p&gt;

&lt;p&gt;This is a common problem type that can be addressed in a few different ways. For this initial example, you’ll keep it brief by including the expression &lt;code&gt;arg = sys.argv[1]&lt;/code&gt; in a try block. Modify the code as follows:&lt;/p&gt;

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

import sys

try:
    file_to_search = sys.argv[1]
except IndexError:
    raise SystemExit("Usage: {} &amp;lt;file_to_search&amp;gt;".format(sys.argv[0]))



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

&lt;/div&gt;

&lt;p&gt;The expression is included in a &lt;code&gt;try&lt;/code&gt; block. Line 6 raises the built-in exception &lt;code&gt;SystemExit&lt;/code&gt;. If no argument is passed to &lt;code&gt;searcher.py&lt;/code&gt;, then the process exits with a status code of 1 after printing the usage. Note the addition of &lt;code&gt;sys.argv[0]&lt;/code&gt; in the error message. It shows the name of the program in the usage message. Now, when you run the same program without any Python command line arguments, you can see the following output:&lt;/p&gt;

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

C:\Users\UserName\Desktop\DevPosts&amp;gt;searcher.py
Usage: C:\Users\UserName\Desktop\DevPosts\searcher.py &amp;lt;file_to_search&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Now that we have made ourselves familiar with how &lt;code&gt;sys.argv&lt;/code&gt; works, we can dive into our little project which is to code a simple file searcher&lt;/p&gt;

&lt;p&gt;first we import the &lt;code&gt;sys&lt;/code&gt; module&lt;/p&gt;

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

import sys


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

&lt;/div&gt;

&lt;p&gt;Next we write checks to make sure we get the right number of arguments from the user&lt;/p&gt;

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

if len(sys.argv) &amp;lt; 3:
    sys.stderr.write("Error: Usage " + sys.argv[0] + " &amp;lt;filename&amp;gt; &amp;lt;words&amp;gt;")
    sys.stderr.flush()
    exit(2)
else:
    filename = sys.argv[1]
    needle = sys.argv[2]


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

&lt;/div&gt;

&lt;p&gt;initalize counter for the number of times we find our needle&lt;/p&gt;

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

counter = 0


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

&lt;/div&gt;

&lt;p&gt;Now we open our file in read mode&lt;/p&gt;

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

file_handler = open(filename)


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

&lt;/div&gt;

&lt;p&gt;Next step is to iterate through the file while separating words in each line by a delimeter (space) and making it into a sentence&lt;/p&gt;

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

for line in file_handler.readlines():
        sentences = line.split(" ")


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

&lt;/div&gt;

&lt;p&gt;Then iterate through the sentences word by word and compare against our needle, and if it is a match, we increment counter&lt;/p&gt;

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

for word in sentences:      
        # this checks if the last word is a new line character and eliminates it        
    if word == sentences[-1]:
        word = word[:-1]            
    if word == needle:              
        counter += 1


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

&lt;/div&gt;

&lt;p&gt;Finally we &lt;code&gt;print&lt;/code&gt; the number of times the word was found&lt;/p&gt;

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

print (str(counter) + " times " + needle + " appears")


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

&lt;/div&gt;

&lt;p&gt;The full code&lt;/p&gt;

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

import sys

if len(sys.argv) &amp;lt; 3:
    sys.stderr.write("Error: Usage " + sys.argv[0] + " &amp;lt;filename&amp;gt; &amp;lt;words&amp;gt;")
    sys.stderr.flush()
    exit(2)
else:
    filename = sys.argv[1]
    needle = sys.argv[2]

counter = 0
file_handler = open(filename)

for line in file_handler.readlines():   
    sentences = line.split(" ")         
    for word in sentences:              
        if word == sentences[-1]:       
            word = word[:-1]            
        if word == needle:              
            counter += 1                

print (str(counter) + " times " + needle + " appears")


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

&lt;/div&gt;

&lt;p&gt;In this tutorial, you've learned about Python command line arguments. You should feel a little prepared to apply this new skills to your code.&lt;/p&gt;

&lt;p&gt;Happy Coding :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>algorithms</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
