<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Rammy Blog]]></title><description><![CDATA[Software Developer with a talent for Backend and Frontend development. Strong knowledge of Javascript, Node, Express, React.js, Svelte, Python, and Django.]]></description><link>https://blog.tundeonasanya.com</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 15:04:13 GMT</lastBuildDate><atom:link href="https://blog.tundeonasanya.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Short Polling vs. Long Polling: Understanding the Differences and When to Use Each]]></title><description><![CDATA[Recently I wrote about the request/response model in backend communication, but this model is not suitable for every type of request. Imagine you want to upload a 50GB video to youtube, this process is very inefficient with the request/response model...]]></description><link>https://blog.tundeonasanya.com/short-polling-vs-long-polling-understanding-the-differences-and-when-to-use-each</link><guid isPermaLink="true">https://blog.tundeonasanya.com/short-polling-vs-long-polling-understanding-the-differences-and-when-to-use-each</guid><category><![CDATA[polling]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[backend]]></category><dc:creator><![CDATA[Babatunde Onasanya]]></dc:creator><pubDate>Tue, 28 Mar 2023 19:13:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680030560164/ab239e10-22b6-47d2-8b85-3d81be581f2d.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recently I wrote about the <a target="_blank" href="https://hashnode.com/post/clfmqbelk05k8swnvex3qhy4y">request/response model</a> in backend communication, but this model is not suitable for every type of request. Imagine you want to upload a 50GB video to youtube, this process is very inefficient with the request/response model because it is going to be a long request. This is where polling comes in.</p>
<h2 id="heading-polling">Polling</h2>
<p>Polling refers to the process of checking the status(getting new data) of a request made by the client to the server at regular intervals. This process of checking the status can occur thousands of times a second.</p>
<h2 id="heading-types-of-polling">Types of polling</h2>
<ol>
<li><p>Short polling</p>
</li>
<li><p>Long polling</p>
</li>
</ol>
<p>Some applications require real-time updates and developers often decide between using short or long polling for backend communication. Short polling is quite easy to implement but it wastes backend resources because it has to make requests several times. Long polling, on the other hand, reduces the number of requests sent but it’s more complicated to implement.</p>
<p>In this article, we'll explore both short polling and long polling, and discuss their pros and cons, using JavaScript as the programming language.</p>
<h2 id="heading-short-polling">Short Polling</h2>
<p>In short polling, the client sends a request to the server, and the server responds with a unique ID while the request will keep processing in the server. The client will send another request using the ID, if there are no updates, the client will send another request, and the process repeats until the server responds with a success status to the client. This technique is useful when a request takes a long time to process, such as uploading a video to YouTube.</p>
<p>Let's go through a code sample, In the example, I will be using JavaScript and the express framework to spin up an HTTP server</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// short-poll.js</span>
<span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> { <span class="hljs-attr">v4</span>: uuidv4 } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'uuid'</span>);

<span class="hljs-keyword">const</span> jobs = {
  <span class="hljs-string">'1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'</span>: <span class="hljs-string">'pending'</span>,
  <span class="hljs-string">'u65675654654-bbfd-4b2d-9b5d-ab8dfbbd4bed'</span>: <span class="hljs-string">'done'</span>,
};

app.post(<span class="hljs-string">'/submit'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> jobId = <span class="hljs-string">`job:<span class="hljs-subst">${uuidv4()}</span>`</span>;
  jobs[jobId] = <span class="hljs-string">'pending'</span>;
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> updateJob(jobId), <span class="hljs-number">10000</span>);
  res.json({ jobId, <span class="hljs-attr">status</span>: jobs[jobId]  });
});

app.get(<span class="hljs-string">'/status'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(jobs[req.query.jobId]);
  res.end(<span class="hljs-string">'\n\nJobStatus: '</span> + jobs[req.query.jobId] + <span class="hljs-string">'%\n\n'</span>);
});

app.listen(<span class="hljs-number">9001</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'listening on 9001'</span>));

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateJob</span>(<span class="hljs-params">jobId</span>) </span>{
  jobs[jobId] = <span class="hljs-string">'done'</span>;
}
</code></pre>
<p>The code above is a simple express server, that uses an object to store data.</p>
<pre><code class="lang-javascript">app.post(<span class="hljs-string">'/submit'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> jobId = <span class="hljs-string">`job:<span class="hljs-subst">${uuidv4()}</span>`</span>;
  jobs[jobId] = <span class="hljs-string">'pending'</span>;
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> updateJob(jobId), <span class="hljs-number">10000</span>);
  res.json({ jobId, <span class="hljs-attr">status</span>: jobs[jobId]  });
});
</code></pre>
<p>The route above is a POST route, that creates a job and set the current state of the job to pending then update it after 10s. The update will happen in the background but it immediately responds with the jobId which the client will use to poll.</p>
<pre><code class="lang-javascript">app.get(<span class="hljs-string">'/status'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(jobs[req.query.jobId]);
  res.end(<span class="hljs-string">'\n\nJobStatus: '</span> + jobs[req.query.jobId] + <span class="hljs-string">'%\n\n'</span>);
});
</code></pre>
<p>This route is where the client will check the status of the job, In our example, we have two different states (pending and done). The client will keep sending requests to this route till the server responds with the done status.</p>
<p>To start the server, run <code>node short-poll.js</code></p>
<p>Now let's test out the code. I will be using postman as the client.</p>
<ol>
<li><p>Send a POST request to this URL <code>localhost:9001/submit</code></p>
</li>
<li><p>It will respond with the jobId. This jobId is what we will use to poll.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679956557739/72c95686-1bab-43b7-a4c4-57fc63f0341b.jpeg" alt class="image--center mx-auto" /></p>
<ol>
<li>Send a GET request to <code>localhost:9001/status?jobId=jobId</code></li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679958198484/aed66614-4041-488e-a81d-bae7b71c404b.jpeg" alt class="image--center mx-auto" /></p>
<ol>
<li>It will return the current state of the job whether it's pending or done. keep doing step 3 till the server responds with done.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1679958337398/6b73708c-df1f-42d6-b7b6-d8b3eb76de8a.jpeg" alt class="image--center mx-auto" /></p>
<p>In this short example, we have seen how easy to implement and how inefficient and resource-wasteful short polling is, as it generates a large number of requests, even when there are no updates.</p>
<h2 id="heading-long-polling">Long Polling</h2>
<p>With Long polling, the client sends a request to the server, if the response required is not ready, the server will keep the request open till there is a suitable response, when the server has the response required, the server will send the response back. This reduces the number of requests sent by the client, making it more efficient than short polling.</p>
<p>Let's go through a simple example of how long polling work with JavaScript</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// long-polling.js</span>

<span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)();
<span class="hljs-keyword">const</span> { <span class="hljs-attr">v4</span>: uuidv4 } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'uuid'</span>);

<span class="hljs-keyword">const</span> jobs = {};

app.post(<span class="hljs-string">'/submit'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> jobId = <span class="hljs-string">`job:<span class="hljs-subst">${uuidv4()}</span>`</span>;
  jobs[jobId] = <span class="hljs-string">'pending'</span>;
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> updateJob(jobId), <span class="hljs-number">20000</span>);
  res.json({ jobId, <span class="hljs-attr">status</span>: jobs[jobId] });
});

app.get(<span class="hljs-string">'/status'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> jobId = req.query.jobId;
  <span class="hljs-comment">//long polling, don't respond until done</span>
  <span class="hljs-keyword">while</span> ((<span class="hljs-keyword">await</span> checkJobComplete(req.query.jobId)) == <span class="hljs-literal">false</span>);
  res.json({ jobId, <span class="hljs-attr">status</span>: jobs[jobId] });
});

app.listen(<span class="hljs-number">9002</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'listening on 9002'</span>));

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkJobComplete</span>(<span class="hljs-params">jobId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (jobs[jobId] !== <span class="hljs-string">'done'</span>) <span class="hljs-built_in">this</span>.setTimeout(<span class="hljs-function">() =&gt;</span> resolve(<span class="hljs-literal">false</span>), <span class="hljs-number">1000</span>);
    <span class="hljs-keyword">else</span> resolve(<span class="hljs-literal">true</span>);
  });
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateJob</span>(<span class="hljs-params">jobId</span>) </span>{
  jobs[jobId] = <span class="hljs-string">'done'</span>;
}
</code></pre>
<p>The code above is similar to the short polling code, the major difference is how we check for the job status.</p>
<pre><code class="lang-javascript">app.post(<span class="hljs-string">'/submit'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> jobId = <span class="hljs-string">`job:<span class="hljs-subst">${uuidv4()}</span>`</span>;
  jobs[jobId] = <span class="hljs-string">'pending'</span>;
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> updateJob(jobId), <span class="hljs-number">20000</span>);
  res.json({ jobId, <span class="hljs-attr">status</span>: jobs[jobId] });
});
</code></pre>
<p>This route submits the job to the server, it returns the jobId and status almost immediately while it updates the job status in the background after the 20s(20000ms).</p>
<pre><code class="lang-javascript">app.get(<span class="hljs-string">'/status'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> jobId = req.query.jobId;
  <span class="hljs-comment">//long polling, don't respond until done</span>
  <span class="hljs-keyword">while</span> ((<span class="hljs-keyword">await</span> checkJobComplete(req.query.jobId)) == <span class="hljs-literal">false</span>);
  res.json({ jobId, <span class="hljs-attr">status</span>: jobs[jobId] });
});
</code></pre>
<p>This is where the long polling happens, this route checks for the status of the job, When a client sends a GET request here, it will keep the connection open with the <code>while</code> loop till it gets a status of done, then it returns to the client then closes the connection.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkJobComplete</span>(<span class="hljs-params">jobId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (jobs[jobId] !== <span class="hljs-string">'done'</span>) <span class="hljs-built_in">this</span>.setTimeout(<span class="hljs-function">() =&gt;</span> resolve(<span class="hljs-literal">false</span>), <span class="hljs-number">1000</span>);
    <span class="hljs-keyword">else</span> resolve(<span class="hljs-literal">true</span>);
  });
}
</code></pre>
<p>This helper function takes a jobId as an argument which is used to check whether a specific job is complete or not. The function returns a Promise that resolves to a Boolean value indicating whether the job is complete or not.</p>
<p>Now let's test, I will use postman as the client.</p>
<ol>
<li><p>Run the server <code>node long-polling.js</code></p>
</li>
<li><p>Send a POST request to this URL <code>localhost:9002/submit</code></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680029250742/72156758-0e96-4fe5-8c94-557cd870657b.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>It will respond with the jobId. This jobId is what we will use to poll.</p>
</li>
<li><p>Then the client will send another GET request to <code>localhost:9002/status?jobId=&lt;jobId&gt;</code></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1680029261155/a6216005-b0de-4d32-98d2-4445d5bd02a2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>This request will not return until it gets a good response from the backend</p>
</li>
</ol>
<p>From the above example, Long polling reduced the number of requests made to the server by the client, making it more efficient than short polling. The downside of this approach is that it can be more complex to implement because the connection needs to be open on the server side till there is new data to be sent to the client.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>When building applications that are real-time, polling can be an option to use and developers will decide on whether to use short polling or long polling to communicate between the client and server side. Short polling can be easy to implement, but it can become inefficient and wasteful of backend resources when too many requests start going in. Long polling, on the other hand, is quite efficient than short polling, because of the reduced number of requests, but it can be more complex to implement.</p>
<p>Code source:</p>
<p><a target="_blank" href="https://github.com/rammyblog/polling-example">https://github.com/rammyblog/polling-example</a></p>
<p>References</p>
<p><a target="_blank" href="https://www.udemy.com/course/fundamentals-of-backend-communications-and-protocols/">https://www.udemy.com/course/fundamentals-of-backend-communications-and-protocols/</a></p>
<p><a target="_blank" href="https://cdn.hashnode.com/res/hashnode/image/upload/v1622211087485/BO8QX86k1.png?w=1600&amp;h=840&amp;fit=crop&amp;crop=entropy&amp;auto=compress,format&amp;format=webp">Image</a></p>
]]></content:encoded></item><item><title><![CDATA[Understanding the Request-Response Model in Backend Communication]]></title><description><![CDATA[One important concept in the modern web application is backend communication, Backend communication simply refers to how several components of the backend, frontend applications and different backend applications communicate with each other.

One of ...]]></description><link>https://blog.tundeonasanya.com/understanding-the-request-response-model-in-backend-communication</link><guid isPermaLink="true">https://blog.tundeonasanya.com/understanding-the-request-response-model-in-backend-communication</guid><category><![CDATA[backend]]></category><category><![CDATA[requestresponse]]></category><dc:creator><![CDATA[Babatunde Onasanya]]></dc:creator><pubDate>Fri, 24 Mar 2023 16:00:39 GMT</pubDate><content:encoded><![CDATA[<p>One important concept in the modern web application is backend communication, Backend communication simply refers to how several components of the backend, frontend applications and different backend applications communicate with each other.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1394/format:webp/1*fPLxbzS5zdJlKrzxf4VVXQ.png" alt="Visual representation of the Request-response model" class="image--center mx-auto" /></p>
<p>One of the most popular patterns for backend communications is the Request-Response Model. In this article, I will discuss how the Request-Response Model works on a high level, how the request is structured and the challenges it poses.</p>
<p>The request-response model is a classic pattern and very common, if you have built a backend application you probably used this model. It involves the client(frontend applications or some other backend applications) sending an HTTP request to the server. Then the server parses the request, After parsing the request it processes the request, performs the necessary operations, and sends a response back to the client. Finally, the client parses and consumes the response.</p>
<h3 id="heading-anatomy-of-the-requestresponse-model">Anatomy of the Request/Response Model</h3>
<p>Before a request is sent, the server has a pre-defined structure that the client has to adhere to, the request structure of the request includes the type of request i.e GET, POST or PUT and the data payload which includes the data that the client wants to send to the server. The request has a boundary which is a sequence of characters that marks the end of one HTTP request and the beginning of another.</p>
<p>On the other hand, the Response structure includes a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status">status code</a>, which tells you whether the request was successful. It also contains the data that the server sends back to the client. Like the request, the response has a boundary defined by a protocol that ensures the message is correctly formatted and can be parsed by the client.</p>
<h3 id="heading-building-a-video-upload-service-with-request-response-model-high-level">Building a Video Upload Service with Request-Response Model (High level)</h3>
<p>There are two different approaches you can take when building a video upload service using the request-response model: sending a large request with the video or chunking the video and sending a request per chunk.</p>
<p>Sending a large request with the video is quite simple and straightforward, where the client can easily send the video to the server, but the issue with this approach is that it can be slow and unstable when dealing with large files, especially when using slower networks.</p>
<p>Chunking the video and sending a request per chunk is much better and it’s a reliable approach. This approach involves splitting the video into smaller chunks, sending each chunk as a separate request, and allowing the server to process each chunk before sending the next. This approach enables the client to resume the upload from where it left off in case of network errors.</p>
<h3 id="heading-challenges-of-the-request-response-model">Challenges of the Request-Response Model</h3>
<p>The Request-Response model is quite popular and very effective model for backend communication but it has limitations. particularly in scenarios that require real-time communication, such as notification services or chatting applications. These applications require a different communication model that enables real-time communication and handles long-running requests.</p>
<p>Another challenge of the Request-Response Model is dealing with very long requests. When a request is too long, it can cause performance issues and result in a slower response time. In such cases, it may be necessary to use alternative methods such as chunking the data.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>The Request-Response Model is a popular and effective model for backend communication. It allows the client and server to communicate easily, with the server processing the request and sending a response back to the client. However, it has its limitations, particularly in scenarios that require real-time communication or handle very long requests. As a developer, it's essential to understand the pros and cons of different communication models and choose the one that best suits the application's needs.</p>
<p>References:</p>
<ul>
<li><p><a target="_blank" href="https://www.udemy.com/course/fundamentals-of-backend-communications-and-protocols/">https://www.udemy.com/course/fundamentals-of-backend-communications-and-protocols/</a></p>
</li>
<li><p><a target="_blank" href="https://medium.com/geekculture/http-the-request-response-cycle-ddcb5bb70707">https://medium.com/geekculture/http-the-request-response-cycle-ddcb5bb70707</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to create multiple independent admin sites in Django]]></title><description><![CDATA[Django framework comes with a powerful part called the admin interface. The admin reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site ( Django official docs ).
With the admin...]]></description><link>https://blog.tundeonasanya.com/how-to-create-multiple-independent-admin-sites-in-django</link><guid isPermaLink="true">https://blog.tundeonasanya.com/how-to-create-multiple-independent-admin-sites-in-django</guid><category><![CDATA[Django]]></category><category><![CDATA[Python]]></category><category><![CDATA[admin]]></category><dc:creator><![CDATA[Babatunde Onasanya]]></dc:creator><pubDate>Wed, 13 Jan 2021 18:03:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1610554809266/37IoVQeX1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Django framework comes with a powerful part called the <strong>admin</strong> interface. The admin reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site ( <a target="_blank" href="https://docs.djangoproject.com/en/3.1/ref/contrib/admin/">Django official docs</a> ).</p>
<p>With the admin interface, You can rapidly perform CRUD operations with any database model. The admin comes with hooks for easy customization.</p>
<p>In this tutorial, I will guide you on how to create multiple independent admin sites. The common method to make the admin interface is to place all models in a single admin. Anyway, it is possible to have different admin pages in a single Django application.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>For this tutorial, we are going to create a simple Django application with two models. Before you begin this tutorial you'll need the </p>
<ul>
<li>Virtual Environment</li>
<li>A web browser</li>
<li>A code editor e.g VSCode</li>
</ul>
<p>Let’s get started…</p>
<h2 id="creating-the-django-application">Creating the Django Application</h2>
<p>Step 1:  Create and activate a virtual environment, I will name the virtual environment venv.</p>
<pre><code>virtualenv venv
<span class="hljs-keyword">source</span> venv/bin/activate
</code></pre><p>You’ll know that your virtual environment has been activated, because your console prompt in the terminal will change. It should look something like this:</p>
<pre><code>(venv) $
</code></pre><p>Step 2: Install the latest version of Django using the command below</p>
<pre><code><span class="hljs-attribute">pip</span> install Django
</code></pre><p>Step 3: Create the Django application, for the purpose of this tutorial we would name the application <strong>core</strong></p>
<pre><code>django-<span class="hljs-keyword">admin</span> startproject core .
</code></pre><p>The folder structure should look like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610548108352/qccUNrVv7.jpeg" alt="django-admin1.jpg" />
Run the application using the command below</p>
<pre><code><span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">runserver</span>
</code></pre><p>Your server should be running on <code>http://127.0.0.1:8000/</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610548049952/bIOdB6ap4.png" alt="Screenshot_2021-01-13 Django the Web framework for perfectionists with deadlines .png" />
<em>Ignore the unapplied migrations message</em></p>
<h2 id="setting-up-the-django-application">Setting up the Django Application</h2>
<p>In the previous section, we created our Django application, now it is time to set it up.
Step 1: Migrate the default tables.</p>
<pre><code> <span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">migrate</span>
</code></pre><p>Step 2: Create a superuser, this superuser account will be used to access the admin pages.</p>
<pre><code><span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">createsuperuser</span>
</code></pre><p>You’ll then be asked to enter a username followed by your email address and password. Once you’ve entered the required details, you’ll be notified that the superuser has been created.</p>
<pre><code><span class="hljs-attribute">Username</span>: admin
Email <span class="hljs-attribute">address</span>: admin<span class="hljs-variable">@example</span>.com
<span class="hljs-attribute">Password</span>:
Password (again):
</code></pre><h2 id="creating-the-app-and-models">Creating the app and models</h2>
<p>Step 1: Create an app called blog.</p>
<pre><code><span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">startapp</span> <span class="hljs-selector-tag">blog</span>
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610548767046/8X7-_JAaF.jpeg" alt="Screenshot from 2021-01-13 15-37-15.jpg" /></p>
<p>Step 2: Open the <code>settings.py</code> file located the core folder(<code>core/settings.py</code>), then edit the INSTALLED_APPS to this</p>
<pre><code><span class="hljs-attr">INSTALLED_APPS</span> = [
    <span class="hljs-string">'django.contrib.admin'</span>,
    <span class="hljs-string">'django.contrib.auth'</span>,
    <span class="hljs-string">'django.contrib.contenttypes'</span>,
    <span class="hljs-string">'django.contrib.sessions'</span>,
    <span class="hljs-string">'django.contrib.messages'</span>,
    <span class="hljs-string">'django.contrib.staticfiles'</span>,
    <span class="hljs-string">'blog'</span>
]
</code></pre><p>Step 3: we need to create two simple models in the blog app called todo and post.  In <code>blog/models.py</code> add the following code</p>
<pre><code><span class="hljs-keyword">from</span> django.db <span class="hljs-keyword">import</span> models

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Todo</span> (<span class="hljs-params">models.Model</span>):</span>
    title = models.CharField(max_length=<span class="hljs-number">100</span>)    

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.title


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Post</span>(<span class="hljs-params">models.Model</span>):</span>
    title = models.CharField(max_length=<span class="hljs-number">500</span>)
    image_url = models.URLField(max_length=<span class="hljs-number">500</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.title
</code></pre><p>After adding the code, we need to makemigrations and migrate, so that the Post and Todo tables can be created in the database</p>
<pre><code><span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">makemigrations</span>
<span class="hljs-selector-tag">python</span> <span class="hljs-selector-tag">manage</span><span class="hljs-selector-class">.py</span> <span class="hljs-selector-tag">migrate</span>
</code></pre><p>Step 4: Add the two models to the admin interface so we can perform crud operations on both models, In <code>blog/admin.py</code> add the following code</p>
<pre><code><span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> <span class="hljs-keyword">admin</span>
<span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> Post, Todo

<span class="hljs-keyword">admin</span>.site.register(Post)
<span class="hljs-keyword">admin</span>.site.register(Todo)
</code></pre><p>After adding the models to the <code>blog/admin.py</code> file you can then start the server(<code>python manage.py runserver</code>), then navigate to <code>http://127.0.0.1:8000/admin/</code>, it will ask you to login, input the superuser details you created earlier. The page should look like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610549858634/8ZurYjL_h.png" alt="image.png" /></p>
<p>Currently, our todo and post models are in the same place. Now we want to split the admins.</p>
<p>We will not tamper with the default admin but rather create an independent admin for post which will be a new subclass of <code>admin.AdminSite</code></p>
<p>In our <code>blog/admin.py</code> we do:</p>
<pre><code><span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> <span class="hljs-keyword">admin</span>
<span class="hljs-keyword">from</span> .models <span class="hljs-keyword">import</span> Post, Todo

<span class="hljs-keyword">class</span> PostAdminSite(<span class="hljs-keyword">admin</span>.AdminSite):
    site_header = "Blog Post admin"
    site_title = "Blog Post Admin Portal"
    index_title = "Welcome to Rammyblog"

post_admin_site = PostAdminSite(<span class="hljs-type">name</span>=<span class="hljs-string">'post_admin'</span>)


post_admin_site.register(Post)
<span class="hljs-keyword">admin</span>.site.register(Todo)
</code></pre><p>I created a new class called PostAdminSite and inherited from admin.AdminSite, then I declared the following varaibles 
site_header is the  HTML tag of the Post Admin Page
site_title is the  HTML tag of the Post Admin Page
index_title will replace the Django Adminstration title on the admin page.</p>
<p>Then I created an Instance of the PostAdminSite class called  post_admin_site, then I registered the Post model there.</p>
<h2 id="routing-the-independent-admin-pages">Routing the independent admin pages</h2>
<p>We already have a separate admin class for the Post model, we just need to find a way to access it on the web interface. 
Step 1: Open <code>core/urls.py</code> change the urls.py to</p>
<pre><code><span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> <span class="hljs-keyword">admin</span>
<span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> <span class="hljs-type">path</span>
<span class="hljs-keyword">from</span> blog.<span class="hljs-keyword">admin</span> <span class="hljs-keyword">import</span> post_admin_site

urlpatterns = [
    path(<span class="hljs-string">'admin/'</span>, <span class="hljs-keyword">admin</span>.site.urls),
    path(<span class="hljs-string">'post-admin/'</span>, post_admin_site.urls)
]
</code></pre><p>This separates the Post admin from the Todo admin. Both admins are available at their respective URLs, <code>http://127.0.0.1:8000/admin/</code> and <code>http://127.0.0.1:8000/post-admin/</code>.</p>
<p>The Post Admin should look like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610551929521/BULUb7kUX.png" alt="image.png" /></p>
<p>while the common admin page should look like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1610551967911/FTnZ9KJVk.png" alt="image.png" /></p>
<p>You can create more models and add them to the admin class you want, you can have a model registered in different admin class as well.</p>
]]></content:encoded></item></channel></rss>