<?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: c a</title>
    <description>The latest articles on DEV Community by c a (@chrisachinga).</description>
    <link>https://dev.to/chrisachinga</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%2F178218%2F6f1d4ca6-be3b-4645-8d9b-5cb47fdc59d1.png</url>
      <title>DEV Community: c a</title>
      <link>https://dev.to/chrisachinga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chrisachinga"/>
    <language>en</language>
    <item>
      <title>basic django authentication flow using mongodb backend</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Tue, 29 Apr 2025 17:13:17 +0000</pubDate>
      <link>https://dev.to/chrisachinga/basic-django-authentication-flow-using-mongodb-backend-49go</link>
      <guid>https://dev.to/chrisachinga/basic-django-authentication-flow-using-mongodb-backend-49go</guid>
      <description>&lt;p&gt;day 2 of my 20 days of django: exploring mongodb as the backend&lt;/p&gt;

&lt;p&gt;some time back, i explored using mongodb with django:&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk" class="crayons-story__hidden-navigation-link"&gt;Trying Out MongoDB database Backend for Django&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/chrisachinga" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F178218%2F6f1d4ca6-be3b-4645-8d9b-5cb47fdc59d1.png" alt="chrisachinga profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/chrisachinga" class="crayons-story__secondary fw-medium m:hidden"&gt;
              c a
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                c a
                
              
              &lt;div id="story-author-preview-content-2316829" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/chrisachinga" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F178218%2F6f1d4ca6-be3b-4645-8d9b-5cb47fdc59d1.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;c a&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 7 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk" id="article-link-2316829"&gt;
          Trying Out MongoDB database Backend for Django
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/django"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;django&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mongodb"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mongodb&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/database"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;database&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;9&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;so for day 2, i decided to revisit it—but this time, with a simple authentication flow. my goal was to test if the mongodb backend now plays nicely with third-party libraries like &lt;code&gt;django-allauth&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  setup &amp;amp; default user flow
&lt;/h2&gt;

&lt;p&gt;mongodb has solid documentation, but i prefer following the official github readme:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mongodb" rel="noopener noreferrer"&gt;
        mongodb
      &lt;/a&gt; / &lt;a href="https://github.com/mongodb/django-mongodb-backend" rel="noopener noreferrer"&gt;
        django-mongodb-backend
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Django MongoDB Backend
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Django MongoDB Backend&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Django MongoDB Backend is a &lt;a href="https://docs.djangoproject.com/" rel="nofollow noopener noreferrer"&gt;Django&lt;/a&gt;
database backend that uses &lt;a href="https://www.mongodb.com/docs/languages/python/pymongo-driver/" rel="nofollow noopener noreferrer"&gt;PyMongo&lt;/a&gt;
to connect to MongoDB.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Documentation written in the style of MongoDB's documentation is available at
&lt;a href="https://www.mongodb.com/docs/languages/python/django-mongodb/current/" rel="nofollow noopener noreferrer"&gt;https://www.mongodb.com/docs/languages/python/django-mongodb/current/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Documentation written in the style of Django's documentation is available at
&lt;a href="https://django-mongodb-backend.readthedocs.io/en/latest/" rel="nofollow noopener noreferrer"&gt;https://django-mongodb-backend.readthedocs.io/en/latest/&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Install&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Use the version of &lt;code&gt;django-mongodb-backend&lt;/code&gt; that corresponds to your version of
Django. For example, to get the latest compatible release for Django 6.0.x:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install django-mongodb-backend==6.0.&lt;span class="pl-k"&gt;*&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Create a project&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;From your shell, run the following command to create a new Django project
called &lt;code&gt;example&lt;/code&gt; using our project template. Make sure the end of the template
URL corresponds to your version of Django (e.g. &lt;code&gt;6.0.x.zip&lt;/code&gt; for any Django
6.0.x version).&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;django-admin startproject example --template https://github.com/mongodb-labs/django-mongodb-project/archive/refs/heads/6.0.x.zip&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;You can check what version of Django you're using with:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;django-admin --version&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Connect to the database&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Navigate to your &lt;code&gt;example/settings.py&lt;/code&gt; file and replace the &lt;code&gt;DATABASES&lt;/code&gt;
setting using…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mongodb/django-mongodb-backend" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;the setup process involves bootstrapping a project from their provided templates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# install the backend&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--pre&lt;/span&gt; django-mongodb-backend&lt;span class="o"&gt;==&lt;/span&gt;5.2.&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# start a new project from the mongodb template&lt;/span&gt;
django-admin startproject example &lt;span class="nt"&gt;--template&lt;/span&gt; https://github.com/mongodb-labs/django-mongodb-project/archive/refs/heads/5.2.x.zip

&lt;span class="c"&gt;# start an app from their sample app template&lt;/span&gt;
python manage.py startapp sample_mflix &lt;span class="nt"&gt;--template&lt;/span&gt; https://github.com/mongodb-labs/django-mongodb-app/archive/refs/heads/5.1.x.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;update your database settings like this:&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;databases&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;django_mongodb_backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mongo_uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;db_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;mongousers&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;code is available here:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/achingachris/mongo-users" rel="noopener noreferrer"&gt;https://github.com/achingachris/mongo-users&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  thoughts on the setup
&lt;/h3&gt;

&lt;p&gt;authentication works out of the box, even with custom user models.&lt;br&gt;&lt;br&gt;
the only issue i had was not running mongo locally—so performance took a hit. but honestly, seeing my django data as mongodb documents? that was deeply satisfying.&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%2Fjgdwggf9p4hdeqcxbq9r.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%2Fjgdwggf9p4hdeqcxbq9r.png" alt="mongodb compass screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;i'm using &lt;a href="https://github.com/farridav/django-jazzmin" rel="noopener noreferrer"&gt;jazzmin&lt;/a&gt; for the admin interface. adds some nice polish.&lt;/p&gt;




&lt;h2&gt;
  
  
  trying django-allauth with mongodb
&lt;/h2&gt;

&lt;p&gt;unfortunately, still no support.&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%2Fhn3hz852zykexc430xp6.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%2Fhn3hz852zykexc430xp6.png" alt="error screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;from the docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"we plan to test compatibility with the following third-party libraries by the ga release:&lt;br&gt;&lt;br&gt;
django-filter, django rest framework, django-allauth, wagtail, django debug toolbar."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.mongodb.com/docs/languages/python/django-mongodb/v5.0/limitations-upcoming/#std-label-django-upcoming-third-party" rel="noopener noreferrer"&gt;source&lt;/a&gt;&lt;br&gt;&lt;br&gt;
code for the test branch:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/achingachris/mongo-users/tree/django-allauth-mongo" rel="noopener noreferrer"&gt;https://github.com/achingachris/mongo-users/tree/django-allauth-mongo&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  final thoughts
&lt;/h3&gt;

&lt;p&gt;i have high hopes for the mongodb django backend. once third-party libraries are supported, it’ll unlock serious potential for real-world projects.&lt;/p&gt;

&lt;p&gt;until then, we wait.&lt;/p&gt;




&lt;h2&gt;
  
  
  see you on the next one
&lt;/h2&gt;

</description>
      <category>django</category>
      <category>web</category>
      <category>python</category>
    </item>
    <item>
      <title>reviewing prelude's django starter template(by Sheena O'Connell)</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Fri, 25 Apr 2025 13:51:43 +0000</pubDate>
      <link>https://dev.to/chrisachinga/reviewing-preludes-django-starter-templateby-sheena-oconnell-3fa6</link>
      <guid>https://dev.to/chrisachinga/reviewing-preludes-django-starter-templateby-sheena-oconnell-3fa6</guid>
      <description>&lt;p&gt;day 1 of my 20 days of django. &lt;/p&gt;

&lt;p&gt;i always have a &lt;a href="https://github.com/ChrisDevCode-Technologies/django-starter" rel="noopener noreferrer"&gt;starter template&lt;/a&gt; for my django projects, but i couldn't help but feel like it does not cover much: fyi - i still have to do deployment configurations on every project and that's overwhelming.&lt;/p&gt;

&lt;p&gt;Sheena O'Connell has an amazing starter template that I think I can pick a few things from it, and most importantly, it shares some of my beliefs ... and it has a big focus on frontend(i always forget about that)&lt;/p&gt;

&lt;p&gt;here's the template:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/preludetech" rel="noopener noreferrer"&gt;
        preludetech
      &lt;/a&gt; / &lt;a href="https://github.com/preludetech/django-seed" rel="noopener noreferrer"&gt;
        django-seed
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Modern Frontend Django template repo&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;There are many excellent Django templates out there. They all have different priorities and opinions.&lt;/p&gt;
&lt;p&gt;This template repo is different from the rest in that it's primary focus is frontend development, and frontend testing.&lt;/p&gt;
&lt;p&gt;You could simply use this repo as a starting point for your own work - download it however you choose, and start adding your own code to the mix.&lt;/p&gt;
&lt;p&gt;Or you can poke around and use this as a learning resource. Make sure you understand how everything was wired up and why certain decisions were made.&lt;/p&gt;
&lt;p&gt;The latter is the best bet if you want to grow your own skills - it's likely that you will have different preferences, you might want to lay out your project in different ways and use different tools. That's perfectly normal. In fact, creating your own opinionated template repo is a useful learning experience :)&lt;/p&gt;
&lt;div class="markdown-heading"&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/preludetech/django-seed" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  setting the template up
&lt;/h2&gt;

&lt;p&gt;i will use pycharm for this&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%2F8nvybyumropoi536plra.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%2F8nvybyumropoi536plra.png" alt="screenshort of pycharm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the documentation looks straightforward.&lt;/p&gt;

&lt;p&gt;we will first need to setup the database(make sure that docker is installed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;dev_db
docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;next is installing django and other dependencies, and the project is using uv(i have never used it before)&lt;/p&gt;

&lt;p&gt;so i need to install it - &lt;a href="https://github.com/astral-sh/uv:" rel="noopener noreferrer"&gt;https://github.com/astral-sh/uv:&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;on mac:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# On macOS and Linux.&lt;/span&gt;
curl &lt;span class="nt"&gt;-LsSf&lt;/span&gt; https://astral.sh/uv/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;uv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;after that: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Then run uv sync - this will set up a virtual environment in a directory called .venv. This environment works in the usual way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;this is actually very easy ...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Going forward, if you need to run a command using this environment you have the option of activating the environment or using the uv run command. Eg uv run pytest&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;then of course setting up tailwind:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i
npm run tailwind_build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;i will disable the social logins for now(too lazy to settup a new app on github). so on config/settings.py:&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;# SOCIALACCOUNT_PROVIDERS = {
#     "github": {
#         "VERIFIED_EMAIL": True,
#         "SCOPE": [
#             "user",
#         ],
#         "APP": {
#             "client_id": env("GITHUB_CLIENT_ID"),
#             "secret": env("GITHUB_SECRET"),
#             "key": "",
#         },
#     }
# }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then follow the steps to run the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# create the database tables&lt;/span&gt;
uv run manage.py migrate

&lt;span class="c"&gt;# make some fake data inside the database tables so you have something to look at&lt;/span&gt;
uv run manage.py fake_news

&lt;span class="c"&gt;# Run the server&lt;/span&gt;
uv run manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;on a successful setup, your app should be running well on port 8000&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%2Fqpvzs8bwobjmzbvdopta.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%2Fqpvzs8bwobjmzbvdopta.png" alt="running the prelude starter template"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  running tests
&lt;/h2&gt;

&lt;p&gt;the template is using playwright(end-to-end testing for modern web apps) for tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://playwright.dev/python/" rel="noopener noreferrer"&gt;https://playwright.dev/python/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to get started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run playwright &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;i think the setup is done... easy, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring the Admin
&lt;/h2&gt;

&lt;p&gt;creating an admin user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv run manage.py createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fgazr8ovo2ntkr81bi2rc.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%2Fgazr8ovo2ntkr81bi2rc.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the template uses unfold - &lt;a href="https://unfoldadmin.com/" rel="noopener noreferrer"&gt;https://unfoldadmin.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the unfold configurations in the config/settings.py:&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;UNFOLD&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;SITE_TITLE&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;News&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;SITE_HEADER&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;News&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# "DASHBOARD_CALLBACK": "config.unfold.dashboard_callback",
&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SHOW_VIEW_ON_SITE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SIDEBAR&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;show_search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;show_all_applications&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;navigation&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;Home&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;icon&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;home&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;link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reverse_lazy&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:index&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;Dashboard&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;icon&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;monitoring&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;link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reverse_lazy&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:dashboard&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;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;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;News&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;collapsible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;Articles&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;icon&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;local_library&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;link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reverse_lazy&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:news_article_changelist&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;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;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;Accounts&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;collapsible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;Users&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;icon&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;person&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;link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reverse_lazy&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:accounts_user_changelist&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;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&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;Groups&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;icon&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;groups&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;link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;reverse_lazy&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:auth_group_changelist&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;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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can learn more about unfold and its configurations here:&lt;br&gt;
&lt;a href="https://unfoldadmin.com/docs/" rel="noopener noreferrer"&gt;https://unfoldadmin.com/docs/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  user authentication
&lt;/h2&gt;

&lt;p&gt;the template uses &lt;a href="https://docs.allauth.org/en/latest/" rel="noopener noreferrer"&gt;django-allauth&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;in the template:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Email/pass registration and authentication&lt;/li&gt;
&lt;li&gt;Email address validation&lt;/li&gt;
&lt;li&gt;Basic email template in place for comms&lt;/li&gt;
&lt;li&gt;Login with Github(disabled it for the moment)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;django allauth configurations in config/settings.py:&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;# AllAuth settings
&lt;/span&gt;
&lt;span class="n"&gt;ACCOUNT_EMAIL_REQUIRED&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;ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE&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;ACCOUNT_EMAIL_VERIFICATION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mandatory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION&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;ACCOUNT_LOGIN_ON_PASSWORD_RESET&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;ACCOUNT_EMAIL_REQUIRED&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;ACCOUNT_USERNAME_REQUIRED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="n"&gt;ACCOUNT_LOGIN_METHODS&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;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;ACCOUNT_USER_MODEL_USERNAME_FIELD&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;ACCOUNT_ADAPTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;accounts.allauth_account_adapter.AccountAdapter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;ALLOW_SIGN_UPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a custom authentication model is set under the &lt;code&gt;accounts&lt;/code&gt; app. a custom user model with email-based authentication instead of the default username-based 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="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;AbstractBaseUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BaseUserManager&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;PermissionsMixin&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseUserManager&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;create_user&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;email&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="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;is_active&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;is_staff&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;is_admin&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="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;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User must have an email address&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="ow"&gt;not&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;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User must have a 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_obj&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="nf"&gt;model&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;user_obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_password&lt;/span&gt;&lt;span class="p"&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;user_obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_staff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;is_staff&lt;/span&gt;
        &lt;span class="n"&gt;user_obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_superuser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;is_admin&lt;/span&gt;
        &lt;span class="n"&gt;user_obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;is_active&lt;/span&gt;
        &lt;span class="n"&gt;user_obj&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;using&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;db&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;user_obj&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_superuser&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;email&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="bp"&gt;None&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_user&lt;/span&gt;&lt;span class="p"&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;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;is_staff&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;is_admin&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="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AbstractBaseUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PermissionsMixin&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;unique&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;full_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;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;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;is_active&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;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;is_staff&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;is_superuser&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;USERNAME_FIELD&lt;/span&gt; &lt;span class="o"&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="n"&gt;EMAIL_FIELD&lt;/span&gt; &lt;span class="o"&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="c1"&gt;# The fields required when user is created. Email and password are required by default
&lt;/span&gt;    &lt;span class="n"&gt;REQUIRED_FIELDS&lt;/span&gt; &lt;span class="o"&gt;=&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;UserManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  conclusion
&lt;/h2&gt;

&lt;p&gt;i love this template because it makes it easier to have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;custom user management with django-allauth&lt;/li&gt;
&lt;li&gt;very straightforward allauth configurations and customizations, comes in handy&lt;/li&gt;
&lt;li&gt;a cool django admin using unfold (i prefer using jazzmin or daisy, but unfold is giving me doubts)&lt;/li&gt;
&lt;li&gt;i finally learned how to use django channels for realtime communications ... pretty awesome&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;fyi: using these learnings to make my template better.&lt;/p&gt;

&lt;p&gt;if you wanna try other starter templates, checkout:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lincolnloop/django-layout/tree/main" rel="noopener noreferrer"&gt;https://github.com/lincolnloop/django-layout/tree/main&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefftriplett/django-startproject" rel="noopener noreferrer"&gt;https://github.com/jefftriplett/django-startproject&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/wsvincent/lithium" rel="noopener noreferrer"&gt;https://github.com/wsvincent/lithium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;see you soon!&lt;/p&gt;

</description>
      <category>django</category>
      <category>web</category>
      <category>python</category>
    </item>
    <item>
      <title>mongodb backend on django</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Fri, 07 Mar 2025 10:17:33 +0000</pubDate>
      <link>https://dev.to/chrisachinga/mongodb-backend-on-django-4agm</link>
      <guid>https://dev.to/chrisachinga/mongodb-backend-on-django-4agm</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/chrisachinga" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F178218%2F6f1d4ca6-be3b-4645-8d9b-5cb47fdc59d1.png" alt="chrisachinga"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Trying Out MongoDB database Backend for Django&lt;/h2&gt;
      &lt;h3&gt;c a ・ Mar 7&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#django&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#mongodb&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#database&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>django</category>
      <category>mongodb</category>
      <category>database</category>
    </item>
    <item>
      <title>Trying Out MongoDB database Backend for Django</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Fri, 07 Mar 2025 10:06:11 +0000</pubDate>
      <link>https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk</link>
      <guid>https://dev.to/chrisachinga/trying-out-mongodb-database-backend-for-django-4hjk</guid>
      <description>&lt;p&gt;I know many developers who use Django, of course with Relational Databases: Postgres, SQL, SQLite. &lt;/p&gt;

&lt;p&gt;Getting the news from &lt;a href="https://dev.to/mongodb"&gt;MongoDB&lt;/a&gt; that the Django MongoDB Backend is now in Public Preview! was crazy!!! and Amazing of course.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1895549533859561728-372" src="https://platform.twitter.com/embed/Tweet.html?id=1895549533859561728"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1895549533859561728-372');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1895549533859561728&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;So I decided to give it a try. I made some rookie mistakes and assumptions(😂😂)&lt;/p&gt;




&lt;p&gt;Initially I thought it would be a simple plug and play configuration, so I started out by testing it in already existing Django project, in this case, my starter template.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ChrisDevCode-Technologies" rel="noopener noreferrer"&gt;
        ChrisDevCode-Technologies
      &lt;/a&gt; / &lt;a href="https://github.com/ChrisDevCode-Technologies/django-starter" rel="noopener noreferrer"&gt;
        django-starter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Django Starter Template
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Django Starter&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/ChrisDevCode-Technologies/django-starter./landing.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FChrisDevCode-Technologies%2Fdjango-starter.%2Flanding.png" alt="landingpage"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/ChrisDevCode-Technologies/django-starter./dashboard.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FChrisDevCode-Technologies%2Fdjango-starter.%2Fdashboard.png" alt="dashboardpage"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Resources Used&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://learndjango.com/tutorials/django-custom-user-model#custom-user-model" rel="nofollow noopener noreferrer"&gt;https://learndjango.com/tutorials/django-custom-user-model#custom-user-model&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://learndjango.com/tutorials/django-allauth-tutorial#django-allauth" rel="nofollow noopener noreferrer"&gt;https://learndjango.com/tutorials/django-allauth-tutorial#django-allauth&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/django-crispy-forms/crispy-tailwind?tab=readme-ov-file" rel="noopener noreferrer"&gt;https://github.com/django-crispy-forms/crispy-tailwind?tab=readme-ov-file&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Resources thinking&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://resend.com/python" rel="nofollow noopener noreferrer"&gt;https://resend.com/python&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://uploadthing.com/" rel="nofollow noopener noreferrer"&gt;https://uploadthing.com/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ChrisDevCode-Technologies/django-starter" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Creating a MongoDB Account &amp;amp; a Cluster
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I have used MongoDB on most javascript-based apps, so I know my around it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can learn more about creating a cluster &lt;a href="https://www.mongodb.com/docs/atlas/tutorial/create-new-cluster/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;A free cluster should work for the testing:&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%2Fb6x53derqk783zpjt3ak.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%2Fb6x53derqk783zpjt3ak.png" alt="screenshot of creating mongo cluster" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you will need to create users to access the database, once that is done, just give it a few minutes for the cluster to build up.&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%2Fg7wa1ouykst2pue3aqr6.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%2Fg7wa1ouykst2pue3aqr6.png" alt="screenshot of creating mongo cluster" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that is done, get the connection string, that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mongodb+srv://chrisdevcode:&amp;lt;db_password&amp;gt;@djangomongo.oybyx.mongodb.net/?retryWrites&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&amp;amp;w&lt;span class="o"&gt;=&lt;/span&gt;majority&amp;amp;appName&lt;span class="o"&gt;=&lt;/span&gt;djangomongo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So I cloned the repo, installed the initial dependencies and add install the &lt;code&gt;django-mongodb-backend&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;django-mongodb-backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then of course update the &lt;code&gt;DATABASE&lt;/code&gt; settings to use MongoDB:&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;DATABASES&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;django_mongodb_backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;connection string URI&amp;gt;&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;Looked easy to me, till I ran migrations:&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%2F9s1e33ekkngj5mm0di0b.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%2F9s1e33ekkngj5mm0di0b.png" alt="migration errors" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, that did go well ...&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%2Ff3dzjx1dqf0nh7c5hdlr.gif" 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%2Ff3dzjx1dqf0nh7c5hdlr.gif" alt="disappointed" width="500" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So back to the article by MongoDB's team:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/mongodb" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&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%2Forganization%2Fprofile_image%2F140%2F9639a040-3c27-4b99-b65a-85e100016d3c.png" alt="MongoDB" width="217" height="300"&gt;
      &lt;div class="ltag__link__user__pic"&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%2Fuser%2Fprofile_image%2F973221%2F0c884491-661f-4a9a-8d56-06c1fa7d06f2.jpg" alt="" width="400" height="400"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/mongodb/django-mongodb-backend-quickstart-4o89" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Django MongoDB Backend Quickstart&lt;/h2&gt;
      &lt;h3&gt;Anaiya for MongoDB ・ Feb 3&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#django&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#mongodb&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#quickstart&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;I asked if one has to start from their starter template:&lt;/p&gt;


&lt;div class="liquid-comment"&gt;
    &lt;div class="details"&gt;
      &lt;a href="/anaiyaraisin"&gt;
        &lt;img class="profile-pic" 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%2Fuser%2Fprofile_image%2F973221%2F0c884491-661f-4a9a-8d56-06c1fa7d06f2.jpg" alt="anaiyaraisin profile image"&gt;
      &lt;/a&gt;
      &lt;a href="/anaiyaraisin"&gt;
        &lt;span class="comment-username"&gt;Anaiya&lt;/span&gt;
      &lt;/a&gt;
      &lt;span class="color-base-30 px-2 m:pl-0"&gt;•&lt;/span&gt;

&lt;a href="https://dev.to/anaiyaraisin/comment/2lh34" class="comment-date crayons-link crayons-link--secondary fs-s"&gt;
  &lt;time class="date-no-year"&gt;
    Feb 6
  &lt;/time&gt;

&lt;/a&gt;

    &lt;/div&gt;
    &lt;div class="body"&gt;
      &lt;p&gt;Thanks for your question &lt;a class="mentioned-user" href="https://dev.to/chrisachinga"&gt;@chrisachinga&lt;/a&gt;! &lt;/p&gt;

&lt;p&gt;We recommend doing so to ensure certain necessities are incorporated, such as MongoDB-specific migrations and having the &lt;code&gt;settings.py&lt;/code&gt; file already modified for you so Django is using an ObjectId value.&lt;/p&gt;

&lt;p&gt;Let me know if you have any other questions, I'd be happy to help. &lt;/p&gt;


    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;That was helpful at the moment, oh and don't use it in production ... yet&lt;/p&gt;


&lt;div class="liquid-comment"&gt;
    &lt;div class="details"&gt;
      &lt;a href="/anaiyaraisin"&gt;
        &lt;img class="profile-pic" 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%2Fuser%2Fprofile_image%2F973221%2F0c884491-661f-4a9a-8d56-06c1fa7d06f2.jpg" alt="anaiyaraisin profile image"&gt;
      &lt;/a&gt;
      &lt;a href="/anaiyaraisin"&gt;
        &lt;span class="comment-username"&gt;Anaiya&lt;/span&gt;
      &lt;/a&gt;
      &lt;span class="color-base-30 px-2 m:pl-0"&gt;•&lt;/span&gt;

&lt;a href="https://dev.to/anaiyaraisin/comment/2lj5i" class="comment-date crayons-link crayons-link--secondary fs-s"&gt;
  &lt;time class="date-no-year"&gt;
    Feb 10
  &lt;/time&gt;

&lt;/a&gt;

    &lt;/div&gt;
    &lt;div class="body"&gt;
      &lt;p&gt;Thanks for your reply &lt;a class="mentioned-user" href="https://dev.to/chrisachinga"&gt;@chrisachinga&lt;/a&gt;, &lt;/p&gt;

&lt;p&gt;So we don't recommend using our library in production until our GA. &lt;br&gt;
For any issues please open a GitHub issue or Jira ticket!&lt;/p&gt;

&lt;p&gt;We appreciate your feedback so much. :)&lt;/p&gt;


    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  So we try using the MongoDB starter …
&lt;/h2&gt;

&lt;p&gt;Following the docs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.mongodb.com/docs/languages/python/django-mongodb/current/" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/languages/python/django-mongodb/current/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So you create a django project from the template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;django-admin startproject quickstart &lt;span class="nt"&gt;--template&lt;/span&gt; https://github.com/mongodb-labs/django-mongodb-project/archive/refs/heads/5.1.x.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then you update the connection string:&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;DATABASES&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;django_mongodb_backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;connection string URI&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;db_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;&amp;lt;database name&amp;gt;&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;You also create an application from a starter template:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py startapp sample_mflix &lt;span class="nt"&gt;--template&lt;/span&gt; https://github.com/mongodb-labs/django-mongodb-app/archive/refs/heads/5.1.x.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After that, I ran my migrations:&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%2Fxbrc2x7eyha0xcr715lt.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%2Fxbrc2x7eyha0xcr715lt.png" alt="database name error" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The error was about the DATABASE setting missing the "NAME" value, so I thought this would fix it:&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;DATABASES&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;name&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;default&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;django_mongodb_backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mongodb+srv://chrisdevcode:&amp;lt;password&amp;gt;@djangomongo.oybyx.mongodb.net/?retryWrites=true&amp;amp;w=majority&amp;amp;appName=djangomongo&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;So that should work, right?&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%2Fo0y1pgunnmk2yzcqhf43.gif" 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%2Fo0y1pgunnmk2yzcqhf43.gif" alt="wrong" width="347" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Confusing right? Maybe I rushed into the fix. So I asked on the forum:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.mongodb.com/community/forums/t/mongodb-django-database-backend/313678/1" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.mongodb.com%2Fcommunity%2Fforums%2Fuploads%2Fdefault%2Foriginal%2F3X%2F0%2F1%2F01d4259c8928db8d3f2370429391688f8622654d.png" height="260" class="m-0" width="260"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.mongodb.com/community/forums/t/mongodb-django-database-backend/313678/1" rel="noopener noreferrer" class="c-link"&gt;
          MongoDB Django Database Backend - Python Frameworks - MongoDB Developer Community Forums
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          [https://jira.mongodb.org/browse/INTPYTHON-535](https://JIRA ISSUE CREATED)  PS: I tried using the mongodb backend to an ongoing django project, but was advised to get started from the template(at least for now). I still want to try the mongodb backend and do some benchmarks on performance as compared to postgres.  I got these two issues, maybe the team can help address, but I’m pretty sure I may have missed a step or something from the official guideline(feel free to criticize my feedback)  set...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.mongodb.com%2Fcommunity%2Fforums%2Fuploads%2Fdefault%2Foptimized%2F3X%2F4%2F4%2F4499311543ceb0d3e905ac979d29c6f7090732f5_2_32x32.png" width="32" height="32"&gt;
        mongodb.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Jeffery A. Clark responded with a couple of fixes:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://www.mongodb.com/community/forums/t/mongodb-django-database-backend/313678/2" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.mongodb.com%2Fcommunity%2Fforums%2Fuploads%2Fdefault%2Foriginal%2F3X%2F0%2F1%2F01d4259c8928db8d3f2370429391688f8622654d.png" height="260" class="m-0" width="260"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://www.mongodb.com/community/forums/t/mongodb-django-database-backend/313678/2" rel="noopener noreferrer" class="c-link"&gt;
          MongoDB Django Database Backend - #2 by Alex_Clark - Python Frameworks - MongoDB Developer Community Forums
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Thank you for using Django MongoDB Backend!  Try including the database name in the URI:  DATABASES = {     "default": django_mongodb_backend.parse_uri("mongodb+srv://chrisdevcode:&amp;lt;pass&amp;gt;@djangomongo.oybyx.mongodb.net/default?retryWrites=true&amp;amp;w=majority&amp;amp;appName=djangomongo"), }  Or try configuring the NAME  setting like this:  DATABASES = {     "default": django_mongodb_backend.parse_uri("mongodb+srv://chrisdevcode:&amp;lt;pass&amp;gt;@djangomongo.oybyx.mongodb.net/?retryWrites=true&amp;amp;w=majority&amp;amp;appName=djangomo...
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.mongodb.com%2Fcommunity%2Fforums%2Fuploads%2Fdefault%2Foptimized%2F3X%2F4%2F4%2F4499311543ceb0d3e905ac979d29c6f7090732f5_2_32x32.png" width="32" height="32"&gt;
        mongodb.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DATABASES&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;django_mongodb_backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mongodb+srv://chrisdevcode:&amp;lt;pass&amp;gt;@djangomongo.oybyx.mongodb.net/?retryWrites=true&amp;amp;w=majority&amp;amp;appName=djangomongo&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;DATABASES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&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;NAME&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or &lt;/p&gt;

&lt;p&gt;(will be available on beta 1)&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;DATABASES&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;default&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;django_mongodb_backend&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mongodb+srv://chrisdevcode:&amp;lt;pass&amp;gt;@djangomongo.oybyx.mongodb.net/?retryWrites=true&amp;amp;w=majority&amp;amp;appName=djangomongo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_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;default&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 fix is well explained on the PR: &lt;a href="https://github.com/mongodb/django-mongodb-backend/pull/249" rel="noopener noreferrer"&gt;https://github.com/mongodb/django-mongodb-backend/pull/249&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Did that work? Yes ...&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%2Fxu6uzh15g75lk9jspdnv.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%2Fxu6uzh15g75lk9jspdnv.png" alt="cluster images" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What To Do next?
&lt;/h2&gt;

&lt;p&gt;Testing and comparing performances with other database backends.&lt;/p&gt;

&lt;p&gt;What I love about this: Deployment will be super easy and quick, especially that connection to MongoDB is by a URI, and hopefully no other stuff needs to be done ... trying that next 👀👀&lt;/p&gt;

&lt;p&gt;This podcast on Django Chat talks about the mongodb database backend on django:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://podcasts.apple.com/ke/podcast/official-django-mongodb-backend-jib-adegunloye/id1451536459?i=1000693987686" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fis1-ssl.mzstatic.com%2Fimage%2Fthumb%2FPodcasts115%2Fv4%2F63%2F5a%2F85%2F635a8540-f898-cd11-bf4d-b6295ca72b99%2Fmza_14475314293469626743.jpg%2F1200x1200bf-60.jpg" height="800" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://podcasts.apple.com/ke/podcast/official-django-mongodb-backend-jib-adegunloye/id1451536459?i=1000693987686" rel="noopener noreferrer" class="c-link"&gt;
          Official Django MongoDB Backen–Django Chat – Apple Podcasts
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Podcast Episode · Django Chat · 19/02/2025 · 1h 3m
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpodcasts.apple.com%2Fassets%2Ffavicon%2Ffavicon-32.png" width="32" height="32"&gt;
        podcasts.apple.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Also another good read:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/mongodb/creating-the-mongodb-database-backend-for-django-1f3caf23a235" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fv2%2Fresize%3Afill%3A88%3A88%2F1%2AKsX3qkqj95ZPqoAdu9DOTA.png" alt="MongoDB"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/mongodb/creating-the-mongodb-database-backend-for-django-1f3caf23a235" class="ltag__link__link" rel="noopener noreferrer"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Creating the MongoDB Database Backend for Django | by MongoDB | MongoDB | Jan, 2025 | Medium&lt;/h2&gt;
      &lt;h3&gt;MongoDB ・ &lt;time&gt;Jan 15, 2025&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fmedium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>django</category>
      <category>mongodb</category>
      <category>database</category>
    </item>
    <item>
      <title>Become a Good Attendee and Listener at Developer Meetups and Tech Conferences</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Wed, 18 Dec 2024 12:18:15 +0000</pubDate>
      <link>https://dev.to/chrisachinga/become-a-good-attendee-and-listener-at-developer-meetups-and-tech-conferences-3887</link>
      <guid>https://dev.to/chrisachinga/become-a-good-attendee-and-listener-at-developer-meetups-and-tech-conferences-3887</guid>
      <description>&lt;p&gt;I have a message for some of you: Stop Just Hoarding Swag! How to Learn at Tech Conferences.&lt;/p&gt;

&lt;p&gt;Theres no shortage of advice on how to deliver amazing talks or workshops at tech conferences, not to mention tips for preparing killer proposals and navigating the call for speakers.&lt;/p&gt;

&lt;p&gt;But what about attendees? Sure, there are guides on becoming a good listener or an engaged participant, but this piece is different. This is about my experience and what makes a great attendee and listener.&lt;/p&gt;

&lt;h2&gt;
  
  
  Organizers &amp;amp; Speakers Sweat: A Behind-the-Scenes Look
&lt;/h2&gt;

&lt;p&gt;Before we dive into how to be a top-tier attendee, lets take a moment to appreciate the efforts it takes to organize a tech event or deliver a talk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Organizers
&lt;/h2&gt;

&lt;p&gt;These folks spend countless hours sometimes days or weeks planning sessions and selecting speakers from an overwhelming pool of Call for Speakers submissions.&lt;/p&gt;

&lt;p&gt;The proposals they review? Often incredible, making the job of picking the best even harder. Now, imagine this: many of these organizers are volunteers. &lt;strong&gt;&lt;em&gt;Yes, volunteers!&lt;/em&gt;&lt;/strong&gt; They do this out of sheer passion for building communities and creating meaningful experiences for attendees like you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speakers
&lt;/h2&gt;

&lt;p&gt;Submitting a proposal isnt a walk in the park. Its like applying for a highly competitive job. Speakers spend hours researching their topics, refining their proposals, and aligning their ideas with the events theme and audience.&lt;/p&gt;

&lt;p&gt;Conferences like &lt;a href="https://us.pycon.org/2025/" rel="noopener noreferrer"&gt;PyCon US&lt;/a&gt;&lt;a href="https://us.pycon.org/2025/" rel="noopener noreferrer"&gt;n US, Dj&lt;/a&gt;&lt;a href="https://2025.djangocon.africa/" rel="noopener noreferrer"&gt;an&lt;/a&gt;&lt;a href="https://us.pycon.org/2025/" rel="noopener noreferrer"&gt;goCon Af&lt;/a&gt;&lt;a href="https://2025.djangocon.africa/" rel="noopener noreferrer"&gt;rica, or DevFests aroun&lt;/a&gt;&lt;a href="https://developers.google.com/community/devfest" rel="noopener noreferrer"&gt;d the gl&lt;/a&gt;obe attract thousands of proposals. To even get accepted, speakers go through rounds of revisions, edits, and proofreads.&lt;/p&gt;

&lt;p&gt;And the work doesnt stop there. Once accepted, these rockstars have to &lt;a href="https://us.pycon.org/2025/" rel="noopener noreferrer"&gt;prepare&lt;/a&gt; their pre&lt;a href="https://2025.djangocon.africa/" rel="noopener noreferrer"&gt;sentations &lt;em&gt;me&lt;/em&gt;&lt;/a&gt;&lt;a href="https://developers.google.com/community/devfest" rel="noopener noreferrer"&gt;&lt;em&gt;ticulous&lt;/em&gt;&lt;/a&gt;&lt;em&gt;ly&lt;/em&gt; fact-checking every detail, perfecting their delivery, and ensuring their content resonates with audiences of varying expertise. Dont even get me started on live demos those nail-biting showcases that can either dazzle or derail a session!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Recognizing this sweat equity makes it all the more important for attendees to show up as active, respectful, and engaged participants. After all, your experience as an attendee is a direct product of someone elses hard work and dedication.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  So Becoming a Great Attendee
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It should be an art ..&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  You Spent Resources to Attend, So Make Them Count
&lt;/h3&gt;

&lt;p&gt;Tech conferences arent cheap. You probably forked out money for tickets, travel, and hotel stays, not to mention the emotional cost of pretending to like the event coffee. Dont let all that go to waste!&lt;/p&gt;

&lt;p&gt;Show up on time, attend sessions, and actively participate. &lt;strong&gt;&lt;em&gt;Resist the urge to sneak out after grabbing the swag bag.&lt;/em&gt;&lt;/strong&gt; Trust me, you didnt travel halfway across the country just for another branded water bottle. Engage with the sessions, ask thoughtful questions, and &lt;em&gt;listen&lt;/em&gt; (more on that next).&lt;/p&gt;

&lt;h3&gt;
  
  
  Listen and Give Constructive Feedback
&lt;/h3&gt;

&lt;p&gt;You came to learn, so act like it. Listening is an underrated superpower at tech events. Dont be the person who spends the keynote scrolling through Twitter, only to raise their hand at the end with, &lt;em&gt;Can you repeat the part about AI ethics?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Take notes, absorb the content, and if something doesnt resonate, give constructive feedback. Organizers and speakers genuinely want to know what worked and what didnt. &lt;strong&gt;But lets keep it classy, folks. This session was awful is not feedback; its trolling.&lt;/strong&gt; Instead, try: The session was insightful, but I wouldve loved more live examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Remember, Youre Not Alone
&lt;/h3&gt;

&lt;p&gt;Newsflash: Other people also paid to attend this event/or attended(if free). Theyre here to learn, network, and maybe snag an extra croissant at breakfast. Respect their experience.&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dont hog the mic during Q&amp;amp;A. A question isnt your time to pitch your startup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be kind in networking spaces. Some folks are nervous, and your small talk could make their day.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Share your insights without dominating the conversation. Nobody likes a one-person panel.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Youre part of a community now. Act like it.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Come Prepared: Gear Up for Technical Sessions
&lt;/h3&gt;

&lt;p&gt;If you know its a technical session, its probably a good idea to bring your laptop and get your hands dirty. Whats the point of attending a live coding workshop if all youre doing is watching the presenter type at the speed of light?&lt;/p&gt;

&lt;p&gt;Seriously, bring your gear. Install the software in advance if theyve sent prep materials. Dont be the person who spends the first 20 minutes of the session trying to configure your environment while everyone else is halfway through building a web app.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pro Tip: Keep some USB cables and a charger handy. Nothing says rookie move like running out of battery mid-session.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dont RSVP for Free Events If You Wont Be Attending
&lt;/h3&gt;

&lt;p&gt;Free events arent an all-you-can-eat buffet where you grab a plate and never sit down. If you RSVP and ghost, youre not just messing with the organizers youre robbing someone else of the chance to attend. Imagine taking a seat from a budding developer who couldve learned something life-changing, just because you &lt;em&gt;thought&lt;/em&gt; you might show up. Be kind: RSVP responsibly. Its not Tinder; dont swipe right unless youre serious!&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Tips for Becoming an Attendee Rockstar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Come Prepared:&lt;/strong&gt; Know the schedule, research the speakers, and jot down questions in advance. Nothing says I belong here like a well-thought-out question during a session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Engage on Social Media:&lt;/strong&gt; Live-tweeting(or whatever were calling it on X these days)? Cool. Posting your notes on LinkedIn? Even better. Just make sure youre not so glued to your phone that you miss the actual event.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Smartly:&lt;/strong&gt; Start with a compliment or a shared takeaway from a session. And please, for the love of tech gods, dont shove your business card into peoples hands like its a limited-time coupon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Respect Everyones Time:&lt;/strong&gt; Whether youre talking to a speaker, organizer, or fellow attendee, be mindful. Nobody wants a 15-minute monologue about your side project at lunch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask Questions Thoughtfully:&lt;/strong&gt; Dont ask a question that was just answered five slides ago. Stay relevant and concise.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Being a great attendee isnt rocket science (unless youre literally at a conference about rocket science). Show up, engage, and respect the effort thats gone into creating the event. Youll leave with more than swag youll gain knowledge, connections, and maybe even a sense of community.&lt;/p&gt;

&lt;p&gt;And remember: The better you are as an attendee, the more value you bring to the whole experience. Now go forth and be the attendee everyone wants at their next tech event!&lt;/p&gt;

&lt;p&gt;NOTE:&lt;br&gt;&lt;br&gt;
For article illustrations, please refer to the post on my Medium page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chrisdevcode.medium.com/become-a-good-attendee-and-listener-at-developer-meetups-and-tech-conferences-c9a88f3141b8" rel="noopener noreferrer"&gt;https://chrisdevcode.medium.com/become-a-good-attendee-and-listener-at-developer-meetups-and-tech-conferences-c9a88f3141b8&lt;/a&gt;&lt;br&gt;
]]&amp;gt;&lt;/p&gt;

</description>
      <category>meetup</category>
      <category>developer</category>
      <category>community</category>
    </item>
    <item>
      <title>Using APIs in Python</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Tue, 02 Jan 2024 17:24:12 +0000</pubDate>
      <link>https://dev.to/chrisachinga/using-apis-in-python-46n5</link>
      <guid>https://dev.to/chrisachinga/using-apis-in-python-46n5</guid>
      <description>&lt;p&gt;Application Programming Interfaces (APIs) are crucial in the world of software development. They serve as the backbone for communication between different software applications. This article explores how to interact with a simple API using Python. We'll use a dummy server set up using JSON-Server, a package that allows you to create a fake API for testing and development purposes.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Setting Up the Dummy Server&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before diving into Python code, let's set up our dummy server. JSON-Server provides a full fake REST API with zero coding in less than a minute(not literally). Here's how you can set it up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node.js&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NPM (Node Package Manager)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install JSON-Server&lt;/strong&gt; : Run &lt;code&gt;npm install -g json-server&lt;/code&gt; to install JSON-Server globally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create a db.json File&lt;/strong&gt; : This file will be a database for your dummy API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start the Server&lt;/strong&gt; : Use the following script to start your JSON-Server.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Interacting with the API using Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With its simplicity and readability, Python is an excellent choice for API interaction. We'll use the &lt;strong&gt;requests&lt;/strong&gt; library, which is a simple HTTP library for Python.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, ensure you have the &lt;strong&gt;requests&lt;/strong&gt; library installed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install requests&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performing CRUD Operations&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read Operation (GET request)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if response.status_code == 200: marvelstars = response.json() print("Fetched Marvel Stars:") for star in marvelstars: print(star)else: print(f"Failed to fetch data. Status code: {response.status_code}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Operation (POST request)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Add a new Marvel star (POST request)new_star = { "id": 73, "rating": 1, "name": "Ngugu Wa Thiongo", "stagename": "Thanos", "powers": "Snaps and annoys people"}response = requests.post(api_url, json=new_star)if response.status_code == 201: print("New Marvel Star added successfully.")else: print(f"Failed to add new Marvel Star. Status code: {response.status_code}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update Operation (PUT request)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Edit an existing Marvel star (PUT request)updated_star = { "id": 3, "rating": 10, "name": "Natasha Romanoff", "stagename": "Black Widow", "powers": "Expert martial artist, marksmanship, and hand-to-hand combat. Skilled spy and master of espionage." }response = requests.put(api_url + "/3", json=updated_star)if response.status_code == 200: print("Marvel Star updated successfully.")else: print(f"Failed to update Marvel Star. Status code: {response.status_code}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Delete Operation (DELETE request)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Delete a Marvel star by ID (DELETE request)star_id_to_delete = 23response = requests.delete(f"{api_url}/{star_id_to_delete}")if response.status_code == 200: print(f"Marvel Star with ID {star_id_to_delete} deleted successfully.")else: print(f"Failed to delete Marvel Star by ID. Status code: {response.status_code}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Using Python to interact with APIs is straightforward and efficient. By following these steps, you can set up a dummy server with JSON-Server and use Python's &lt;strong&gt;requests&lt;/strong&gt; library to perform various CRUD operations. This forms a foundational skill for any developer looking to integrate different software applications or services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/achingachris/fetch-and-get" rel="noopener noreferrer"&gt;https://github.com/achingachris/fetch-and-get&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building Progressive Web Apps in Angular (using pwafire)</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Tue, 12 Dec 2023 21:21:03 +0000</pubDate>
      <link>https://dev.to/chrisachinga/building-progressive-web-apps-in-angular-using-pwafire-5ejk</link>
      <guid>https://dev.to/chrisachinga/building-progressive-web-apps-in-angular-using-pwafire-5ejk</guid>
      <description>&lt;p&gt;Progressive Web Apps(PWA) are basically sites that use modern web tools to provide app-like experiences to users. &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://web.dev/explore/progressive-web-apps" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--xL-nfbuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://web.dev/static/images/social-wide.jpg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://web.dev/explore/progressive-web-apps" rel="noopener noreferrer" class="c-link"&gt;
          Progressive Web Apps  |  web.dev
        &lt;/a&gt;
      &lt;/h2&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--D0lIbD_i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.gstatic.com/devrel-devsite/prod/v4c72fb03a7a581549fb317877b3b0627265bda97bd9ba2a29365d1ada8a00354/web/images/favicon.png" width="33" height="32"&gt;
        web.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Progressive Web Apps (PWA) are built and enhanced with modern APIs to deliver enhanced capabilities, reliability, and installability while reaching &lt;em&gt;anyone, anywhere, on any device&lt;/em&gt; with a single codebase: &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://web.dev/articles/what-are-pwas" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--a6vYKSON--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://web.dev/static/articles/what-are-pwas/image/a-graph-illustrating-rel-8f0fbfba2c3e8.svg" height="367" class="m-0" width="370"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://web.dev/articles/what-are-pwas" rel="noopener noreferrer" class="c-link"&gt;
          What are Progressive Web Apps?  |  Articles  |  web.dev
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          An introduction to Progressive Web Apps (PWAs) and the three pillars that separate them from other web apps.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--D0lIbD_i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.gstatic.com/devrel-devsite/prod/v4c72fb03a7a581549fb317877b3b0627265bda97bd9ba2a29365d1ada8a00354/web/images/favicon.png" width="33" height="32"&gt;
        web.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;PWAs is very interesting topic when it comes to user experiences and why businesses would use it. It comes down to users needs and organization goals and agenda, but hear me out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PWAs are faster than traditional websites.&lt;/strong&gt; This is because they are able to cache content locally, which means that they can load much faster, even on slow internet connections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWAs are more reliable than traditional websites.&lt;/strong&gt; This is because they are not reliant on the internet in order to function. Once a PWA has been installed, it can be used offline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWAs are more engaging than traditional websites.&lt;/strong&gt; This is because they can offer a number of features that are not available on traditional websites, such as push notifications and home screen icons.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWAs can be installed on users' home screens.&lt;/strong&gt; This makes them more likely to be used, as they are always just a tap away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWAs can lead to increased conversion rates.&lt;/strong&gt; This is because they offer a more seamless and engaging user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWAs can lead to more repeat visitors.&lt;/strong&gt; This is because they are more likely to be used than traditional websites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWAs can lead to higher revenue.&lt;/strong&gt; This is because they can lead to increased conversion rates and more repeat visitors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, there are a number of reasons why businesses are using PWAs. They offer a number of benefits over traditional websites, and they can help businesses to achieve their goals.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Angular Support PWA?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nZGw9yuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702321612295_DevFest%2BRift%2BValley%2B-%2BAngular%2BPWA%2B%2Bpwafire.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nZGw9yuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702321612295_DevFest%2BRift%2BValley%2B-%2BAngular%2BPWA%2B%2Bpwafire.png" alt="chris achinga" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simply, service workers.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://angular.dev/ecosystem/service-workers/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--VGnAAo5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://angular.dev/assets/images/ng-image.jpg" height="420" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://angular.dev/ecosystem/service-workers/" rel="noopener noreferrer" class="c-link"&gt;
          Service Workers &amp;amp; PWAs • Overview • Angular
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          The web development framework for building modern apps.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--iN_SMQRJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://angular.dev/assets/icons/favicon-32x32.png" width="32" height="32"&gt;
        angular.dev
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;At its simplest, a service worker is a script that runs in the web browser and manages caching for an application.&lt;/p&gt;

&lt;p&gt;A service worker acts as a proxy between web applications, browser and the network(if available). They enhance applications to deliver a reliable user experience and performance.&lt;/p&gt;

&lt;p&gt;Adding a service worker on an Angular app is the first step to creating a PWA(in Angular).&lt;/p&gt;

&lt;p&gt;Service Workers helps single-page applications built with Angular get best performance and makes the applications highly reliable. All this is done without the need to code against low level APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  So… How do you have these service workers in your Angular app?
&lt;/h3&gt;

&lt;p&gt;Pretty simple actually. You just need to run this command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng add @angular/pwa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Okay, this command does a couple of things to make that Angular app you have a PWA, here’s a breakdown:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adds the &lt;code&gt;@angular/service-worker&lt;/code&gt; package to your project, which in turn creates a service worker, and supports service worker builds in the CLI.&lt;/li&gt;
&lt;li&gt;Updates the &lt;code&gt;index.html&lt;/code&gt; file:

&lt;ul&gt;
&lt;li&gt;Includes a link to add the &lt;code&gt;manifest.webmanifest&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Adds a meta tag for &lt;code&gt;theme-color&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Creates the service worker configuration file called &lt;code&gt;[ngsw-config.json](https://angular.dev/ecosystem/service-workers/config)&lt;/code&gt;, which specifies the caching behaviors and other settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To make it happen, you may need to build you app (again 🤣 )&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;PS: You can actually get in depth content on the service workers on the Angular Docs, it’s are surprisingly well documented tbh 🤓 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://angular.dev/ecosystem/service-workers"&gt;https://angular.dev/ecosystem/service-workers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happens when you run your app? The fastest way to identify a PWA is by checking the intstall icon on a Chrom address bar, just like the image below =&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pqoFx775--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702405633742_Screenshot%2B2023-12-12%2Bat%2B21.27.04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pqoFx775--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702405633742_Screenshot%2B2023-12-12%2Bat%2B21.27.04.png" alt="chris achinga" width="738" height="490"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  PWAFIRE … (wth is that)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HIzUJRMm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702405797576_DevFestPwani%2B23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HIzUJRMm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702405797576_DevFestPwani%2B23.png" alt="best software developer" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s not related to fire, or any of the 4 elements of the earth, It’s just collection of resources/APIs used to build Progressive Web Apps.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://pwafire.org/" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--tLWKuYby--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pwafire.org/images/pwafirebanner.jpg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://pwafire.org/" rel="noopener noreferrer" class="c-link"&gt;
          Home - Progressive Web Apps API of APIs
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Resources to build Progressive Web Apps
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--9wcOI4vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pwafire.org/images/icons/pwafire32white.png" width="32" height="32"&gt;
        pwafire.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;PWA brings alot to the table, with 22 APIs for developers to explore! My best APIs from pwafire:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connectivity&lt;/li&gt;
&lt;li&gt;Copy Image&lt;/li&gt;
&lt;li&gt;Copy Text&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Custom install&lt;/li&gt;
&lt;li&gt;Share&lt;/li&gt;
&lt;li&gt;Display mode&lt;/li&gt;
&lt;li&gt;Fullscreen&lt;/li&gt;
&lt;li&gt;Idle detection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can check others out (my opinions can be sad).&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://docs.pwafire.org/get-started" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ePVslsrY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.pwafire.org/images/pwabanner.jpeg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://docs.pwafire.org/get-started" rel="noopener noreferrer" class="c-link"&gt;
          Home - Progressive Web Apps APIs by pwafire
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Documentation for Progressive Web Apps API of APIs - pwafire. PWAFire APIs are modern web apis bundled together into a single package or api aka pwafire. Built on top of Project Fugu, an effort to close gaps in the web's capabilities and native mobile and desktop apps.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EiApr_mx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.pwafire.org/images/icons/icon-96x96.png" width="96" height="96"&gt;
        docs.pwafire.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Code and Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rQVXm_Ae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702409388291_DevFestPwani%2B23%2B1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rQVXm_Ae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702409388291_DevFestPwani%2B23%2B1.png" alt="chris achinag" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a funny one, a simple Angular app that is a PWA using some pwafire APIs to make it cool.&lt;/p&gt;

&lt;p&gt;Incase you’re more of a not-long read, here’s the source:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/achingachris"&gt;
        achingachris
      &lt;/a&gt; / &lt;a href="https://github.com/achingachris/dad-jokes"&gt;
        dad-jokes
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Simple Angular App for Dad Jokes: Angular + Progressive web Apps using PWAFIRE
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Dad jokes&lt;/h1&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/achingachris/dad-jokes"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Using the Share and Copy Text API to make a Progressive Web App. &lt;/p&gt;

&lt;p&gt;From the source code on the repo shared, we will focus on the &lt;a href="https://github.com/achingachris/dad-jokes/blob/main/src/app/app.component.ts"&gt;app.component.ts&lt;/a&gt; file:&lt;/p&gt;

&lt;p&gt;Remeber to install pwafire in your application by running the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm i pwafire --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Using Copy Text API:
&lt;/h3&gt;

&lt;p&gt;This API is used for reading and writing text data to the clipboard, without blocking the main thread.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.pwafire.org/copy-text"&gt;https://docs.pwafire.org/copy-text&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The copy text API usage is as follows:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const text = "Text to copy"          
  pwa.copyText(text);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;So, inside our application, we wil get the tex from the API response:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  async copyJoke(joke: string) {
    try {
      const res = await pwa.copyText(joke);
      this.jokeCopied = res.ok;
      setTimeout(() =&amp;gt; (this.jokeCopied = false), 5000);
    } catch (error) {
      console.log(error);
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Using Share API:
&lt;/h3&gt;

&lt;p&gt;Share links, text and files to other apps installed on the device.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://docs.pwafire.org/web-share" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ePVslsrY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.pwafire.org/images/pwabanner.jpeg" height="450" class="m-0" width="800"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://docs.pwafire.org/web-share" rel="noopener noreferrer" class="c-link"&gt;
          Home - Progressive Web Apps APIs by pwafire
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Documentation for Progressive Web Apps API of APIs - pwafire. PWAFire APIs are modern web apis bundled together into a single package or api aka pwafire. Built on top of Project Fugu, an effort to close gaps in the web's capabilities and native mobile and desktop apps.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--EiApr_mx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.pwafire.org/images/icons/icon-96x96.png" width="96" height="96"&gt;
        docs.pwafire.org
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;To use the share API, you first define the content to be shared:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const data = {
    title: "Some title..",
    text: "Some text...",
    url: "https://pwafire.org",
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And finaly share the data:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pwa.Share(data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, here is how it’s used inside our app:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  async shareJoke() {
    const shareOptions = {
      title: 'Check out this joke!',
      text: this.joke,
      url: 'https://dadjokes-phi.vercel.app/',
    };

    try {
      await pwa.Share(shareOptions);
    } catch (error) {
      console.log(error);
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Simple right!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ImDc7CKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702414591512_DevFest%2BRift%2BValley%2B-%2BAngular%2BPWA%2B%2Bpwafire%2B1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ImDc7CKs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://paper-attachments.dropboxusercontent.com/s_48BA96212B8E2A10194E9CA424DC7AA6BF9595A2C8B2E557026E0977387E22B1_1702414591512_DevFest%2BRift%2BValley%2B-%2BAngular%2BPWA%2B%2Bpwafire%2B1.png" alt="demo" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can checkout the live demo here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dadjokes-pwa.vercel.app/"&gt;https://dadjokes-pwa.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it good people. By the way, there’s alot to learn in the PWA topic, I will drop some links below, just incase you are interested. Especially if you are curious on whether you can add a Progressive Web App to playstore 😎 &lt;/p&gt;

&lt;p&gt;Pwafire documentation: &lt;a href="https://docs.pwafire.org/"&gt;https://docs.pwafire.org/&lt;/a&gt;&lt;br&gt;
Adding a PWA on Google Playstore: &lt;a href="https://developers.google.com/codelabs/pwa-in-play#0"&gt;https://developers.google.com/codelabs/pwa-in-play#0&lt;/a&gt;&lt;br&gt;
Fugu API tracker: &lt;a href="https://fugu-tracker.web.app/"&gt;https://fugu-tracker.web.app/&lt;/a&gt;&lt;br&gt;
Fugu APIs: &lt;a href="https://developers.google.com/learn/pathways/fugu-apis"&gt;https://developers.google.com/learn/pathways/fugu-apis&lt;/a&gt;&lt;br&gt;
Angular Service Workers: &lt;a href="https://angular.dev/ecosystem/service-workers"&gt;https://angular.dev/ecosystem/service-workers&lt;/a&gt;&lt;br&gt;
Explore PWA: &lt;a href="https://web.dev/explore/progressive-web-apps"&gt;https://web.dev/explore/progressive-web-apps&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>angular</category>
      <category>serviceworkers</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Navigating the Code: A Comparative Analysis of CodiumAI PR-Agent and GitHub Copilot in Code Assistance and Review</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Sat, 02 Dec 2023 12:17:09 +0000</pubDate>
      <link>https://dev.to/chrisachinga/navigating-the-code-a-comparative-analysis-of-codiumai-pr-agent-and-github-copilot-in-code-assistance-and-review-22m1</link>
      <guid>https://dev.to/chrisachinga/navigating-the-code-a-comparative-analysis-of-codiumai-pr-agent-and-github-copilot-in-code-assistance-and-review-22m1</guid>
      <description>&lt;p&gt;&lt;a href="https://codium.ai/" rel="noopener noreferrer"&gt;CodiumAI&lt;/a&gt; is a tool that helps developers write meaningful tests for their code. It does this by analyzing the code and generating tests that cover different edge cases and behaviors. CodiumAI can also help developers find suspicious behaviors in their code and improve the overall quality of their code.&lt;/p&gt;

&lt;p&gt;One of the most amazing product by CodiumAI is the &lt;a href="https://www.codium.ai/products/git-plugin/" rel="noopener noreferrer"&gt;PR-Agent&lt;/a&gt;. It helps saving time in reviewing Pull Requests. The tool is open-source and available on GitHub to help alld developers review and manage pull requests (PRs) more efficiently.&lt;/p&gt;

&lt;p&gt;This article is going to explore the features the CodiumAI PR-Agent has to offer in comparison to what GitHub Co-Pilot brings to the table. GitHub Co-Pilot is an AI driven developer tool, developed and maintained by GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up and Installation
&lt;/h2&gt;

&lt;p&gt;Unlike GitHub Co-Pilot(10USD per month), CodiumAI PR-Agent has a flexible pricing options, including free tier, that comes with with great features including Code Behavior Analysis.&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%2Fz1oixeifuoj73re3jldy.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%2Fz1oixeifuoj73re3jldy.png" alt="image 1: codium ai" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get started, you go to &lt;a href="https://www.codium.ai/" rel="noopener noreferrer"&gt;https://www.codium.ai/&lt;/a&gt; and sign up for an account. After creating, you are directed to an app home page where you get to view integration options to different IDE’s including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio Code&lt;/li&gt;
&lt;li&gt;Webstorm&lt;/li&gt;
&lt;li&gt;Pycharm&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;a href="https://app.qodo.ai/" rel="noopener noreferrer"&gt;
      app.qodo.ai
    &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;CodiumAI Visual Studio Code extension is available on the official &lt;a href="https://marketplace.visualstudio.com/items?itemName=Codium.codium" rel="noopener noreferrer"&gt;VSCode market&lt;/a&gt; place.&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%2Fmw7q9nxvw507s6od8mj2.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%2Fmw7q9nxvw507s6od8mj2.png" alt="image2" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installing, you will be redirected to you CodiumAI account to link your profile, and viola! You are good to go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparing CodiumAI PR-Agent and GitHub Co-Pilot
&lt;/h2&gt;

&lt;p&gt;CodiumAI's PR-Agent and GitHub Co-Pilot are both powerful tools, each offering great and unique  features tailored to developers' needs. One amazing advantage of CodiumAI's PR-Agent lies in its free availability for individual developers, providing an accessible and cost-effective solution for enhancing code quality.&lt;/p&gt;

&lt;p&gt;When it comes to user interface, CodiumAI stands out with its proprietary testing-specific UI/UX, that is well integrated into IDEs like Visual Studio Code(see image below). This interface not only facilitates easy management and interaction with individual tests but also enables automatic fixes to code—a feature that GitHub Co-Pilot doesn't explicitly emphasize. This emphasis on user-friendly interfaces positions CodiumAI as a more intuitive and efficient choice for developers.&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%2F4jdjiuu9y6wp86usdp2u.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%2F4jdjiuu9y6wp86usdp2u.png" alt="image3" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CodiumAI supports the most commonly and prefered IDEs by developers worldwide, including VS Code and JetBrains, PyCharm and WebStorm offering flexibility to a broad user base. This contrasts with GitHub Co-Pilot, which, while supporting various IDEs, may not cover the full spectrum of developers' preferences.&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%2Fc3vb0pac2rzzr6fnf9qv.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%2Fc3vb0pac2rzzr6fnf9qv.png" alt="image4" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entry level developers often face challenges in extracting structured and consistent output from generative AI models. CodiumAI addresses this by leveraging its backend capabilities to ensure high-value results from the outset, simplifying the user experience for those new to the platform. GitHub Co-Pilot partially supports this through commands but may require more effort from beginners.&lt;/p&gt;

&lt;p&gt;One distinctive feature of CodiumAI PR-Agent is its ability to run generated tests and Pull Request Commands within the IDE plugin, allowing developers to directly apply and review fixes to their code. This integration of testing and code enhancement sets CodiumAI apart, providing a seamless experience that GitHub Co-Pilot may not fully replicate.&lt;/p&gt;

&lt;p&gt;CodiumAI goes beyond the generation of naive sanity tests by employing Behavior Coverage analysis and static code analysis techniques. This results in the creation of diverse test suites, enhancing the overall quality and effectiveness of the testing process—a dimension where GitHub Co-Pilot may have limitations.&lt;/p&gt;

&lt;p&gt;Moreover, CodiumAI's emphasis on mapping component behaviors and providing a metric for evaluating behavior coverage instills confidence in developers. This feedback mechanism ensures users have a clear understanding of how much of the overall behaviors are covered, a feature that GitHub Co-Pilot may not offer at the same level.&lt;/p&gt;

&lt;p&gt;CodiumAI's PR-Agent emerges as a compelling choice for developers seeking a comprehensive, user-friendly, and privacy-focused solution for code generation and testing. With its unique features and commitment to best practices, CodiumAI offers a robust alternative to GitHub Co-Pilot, particularly for those prioritizing ease of use, testing diversity, and data privacy.&lt;/p&gt;

&lt;p&gt;GitHub Copilot  helps developers work faster by providing suggestions for code completion, code generation, and code explanation. The primary role of GitHub’s CoPilot is code completions and code generation, while CodiumAI PR-Agent is focused on helping developers review pull requests, which it automatically analyzes pull requests and provides feedback on the code, documentation, and overall quality of the changes. &lt;br&gt;
This can help developers identify and fix potential bugs and security issues before they are merged into the codebase.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature Group&lt;/th&gt;
&lt;th&gt;CodiumAI PR-Agent&lt;/th&gt;
&lt;th&gt;GitHub Co-Pilot&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primary Focus&lt;/td&gt;
&lt;td&gt;Pull request review&lt;/td&gt;
&lt;td&gt;Code completion and generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key features&lt;/td&gt;
&lt;td&gt;- Auto description&lt;br&gt;- Auto Pull Request review&lt;br&gt;- Question answering&lt;br&gt;- Code suggestions&lt;br&gt;- Update changelog&lt;br&gt;- Find similar code issues&lt;br&gt;- Add documentation&lt;/td&gt;
&lt;td&gt;- Code suggestions&lt;br&gt;- Code generation&lt;br&gt;- Code explanation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;- Open Source&lt;br&gt;- Paid Features&lt;/td&gt;
&lt;td&gt;Paid Features&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CodiumAI PR-Agent's open-source nature makes it a cost-effective solution, while its support for various programming languages and IDE integrations ensures wide compatibility.&lt;/p&gt;

&lt;p&gt;In conclusion, CodiumAI PR-Agent emerges as a more comprehensive and valuable tool for developers seeking to enhance code quality, streamline pull request reviews, and minimize development risks. &lt;/p&gt;

&lt;p&gt;CodiumAI PR-Agent’s open-source nature, language versatility, and IDE integrations further strengthen its appeal.&lt;/p&gt;

&lt;p&gt;While GitHub Copilot has amazing advantages to Developers like offering a great assistance in writting better code by offering suggestions for code completion, code generation, and code explanation, CodiumAI PR-Agent brings the following to the table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-World Practicality:&lt;/strong&gt; PR-Agent prioritizes practicality by limiting each tool (review, improve, ask, etc.) to a single GPT-4 call, ensuring responsiveness (~30 seconds) and cost-effectiveness for everyday team usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PR Compression Strategy:&lt;/strong&gt; PR-Agent's unique PR Compression strategy effectively handles both short and long PRs, making it a versatile tool for various code review scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modular and Customizable Tools:&lt;/strong&gt; PR-Agent's JSON prompting strategy enables modularity and customization, allowing users to control tool categories and easily add new ones through the configuration file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broad Support and Flexibility:&lt;/strong&gt; PR-Agent supports multiple git providers (GitHub, Gitlab, Bitbucket, CodeCommit), multiple usage methods (CLI, GitHub Action, GitHub App, Docker, etc.), and multiple models (GPT-4, GPT-3.5, Anthropic, Cohere, Llama2), catering to diverse user preferences and environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-Source Community:&lt;/strong&gt; PR-Agent is an open-source project, embracing community contributions and fostering collaboration for continuous improvement.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  A Look Into CodiumAI PR-Agent
&lt;/h2&gt;

&lt;p&gt;To have a look of the PR-Agent in action, we will use an existing project on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/achingachris" rel="noopener noreferrer"&gt;
        achingachris
      &lt;/a&gt; / &lt;a href="https://github.com/achingachris/dad-jokes" rel="noopener noreferrer"&gt;
        dad-jokes
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Simple Angular App for Dad Jokes: Angular + Progressive web Apps using PWAFIRE
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Dad jokes&lt;/h1&gt;

&lt;/div&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/achingachris/dad-jokes" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Clone the project into your development environment and create a new branch, make a few changes, and push to GitHub:&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%2Fa32lkhxl3dxd0jh1rdet.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%2Fa32lkhxl3dxd0jh1rdet.png" alt="image5" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The PR-Agent has a couple of commands that can be used inside a Pull Request:&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%2Ffg4sqkgeavh3c3yd1gmg.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%2Ffg4sqkgeavh3c3yd1gmg.png" alt="image6" width="800" height="873"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;/describe&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/review&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/improve&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/ask&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/docstring&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/commit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;/changelog&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  /describe command
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/qodo-ai" rel="noopener noreferrer"&gt;
        qodo-ai
      &lt;/a&gt; / &lt;a href="https://github.com/qodo-ai/pr-agent" rel="noopener noreferrer"&gt;
        pr-agent
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🚀 PR-Agent (Qodo Merge open-source): An AI-Powered 🤖 Tool for Automated Pull Request Analysis, Feedback, Suggestions and More! 💻🔍
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;div&gt;

  
  
  &lt;img src="https://camo.githubusercontent.com/0b96036091992c964d86249a11352a71ad6a92e656d460523c1604ec78341a1a/68747470733a2f2f636f6469756d2e61692f696d616765732f70725f6167656e742f6c6f676f2d6c696768742e706e67" alt="logo" width="330"&gt;

&lt;br&gt;
&lt;p&gt;&lt;a href="https://qodo-merge-docs.qodo.ai/installation/" rel="nofollow noopener noreferrer"&gt;Installation Guide&lt;/a&gt; |
&lt;a href="https://qodo-merge-docs.qodo.ai/usage-guide/" rel="nofollow noopener noreferrer"&gt;Usage Guide&lt;/a&gt; |
&lt;a href="https://qodo-merge-docs.qodo.ai/tools/" rel="nofollow noopener noreferrer"&gt;Tools Guide&lt;/a&gt; |
&lt;a href="https://qodo-merge-docs.qodo.ai/overview/pr_agent_pro/" rel="nofollow noopener noreferrer"&gt;Qodo Merge&lt;/a&gt; 💎&lt;/p&gt;
&lt;p&gt;PR-Agent aims to help efficiently review and handle pull requests, by providing AI feedback and suggestions&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/qodo-merge-ai-powered-cod/ephlnjeghhogofkifjloamocljapahnl" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b6838baf0ab2eb06d176380a5504c9c165cef007d436e4e32bcdde4d958c3b23/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4368726f6d652d457874656e73696f6e2d76696f6c6574" alt="Static Badge"&gt;&lt;/a&gt;
&lt;a href="https://github.com/apps/qodo-merge-pro/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/86ecc0f10b954ad1b14adc1d393b0c8c4fdd35e3b507ce287c3e1130c9e1c1b2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f50726f2d4170702d626c7565" alt="Static Badge"&gt;&lt;/a&gt;
&lt;a href="https://github.com/apps/qodo-merge-pro-for-open-source/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5d8456b8e1cbe0509c98da0342cd6b47814e6c4ef8206d3ca7e03ec372e915c3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f70656e536f757263652d4170702d726564" alt="Static Badge"&gt;&lt;/a&gt;
&lt;a href="https://discord.com/channels/1057273017547378788/1126104260430528613" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f459d1b93fdf8b41cff9dd4dc80e00ca15f4c6045c70f3a69afef21595b318fb/68747470733a2f2f62616467656e2e6e65742f62616467652f69636f6e2f646973636f72643f69636f6e3d646973636f7264266c6162656c26636f6c6f723d707572706c65" alt="Discord"&gt;&lt;/a&gt;
&lt;a href="https://github.com/Codium-ai/pr-agent/commits/main" rel="noopener noreferrer"&gt;
&lt;img alt="GitHub" src="https://camo.githubusercontent.com/8d3149958ffa96dec83de07c5b3743259f3f8f3db88cde15e0c0504aac83762f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6173742d636f6d6d69742f436f6469756d2d61692f70722d6167656e742f6d61696e3f7374796c653d666f722d7468652d6261646765" height="20"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/qodo-ai/pr-agent#news-and-updates" rel="noopener noreferrer"&gt;News and Updates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/qodo-ai/pr-agent#overview" rel="noopener noreferrer"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/qodo-ai/pr-agent#example-results" rel="noopener noreferrer"&gt;Example results&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/qodo-ai/pr-agent#try-it-now" rel="noopener noreferrer"&gt;Try it now&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qodo-merge-docs.qodo.ai/overview/pr_agent_pro/" rel="nofollow noopener noreferrer"&gt;Qodo Merge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/qodo-ai/pr-agent#how-it-works" rel="noopener noreferrer"&gt;How it works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/qodo-ai/pr-agent#why-use-pr-agent" rel="noopener noreferrer"&gt;Why use PR-Agent?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;News and Updates&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Feb 28, 2025&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;A new version, v0.27, was released. See release notes &lt;a href="https://github.com/qodo-ai/pr-agent/releases/tag/v0.27" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Feb 27, 2025&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Updated the default model to &lt;code&gt;o3-mini&lt;/code&gt; for all tools. You can still use the &lt;code&gt;gpt-4o&lt;/code&gt; as the default model by setting the &lt;code&gt;model&lt;/code&gt; parameter in the configuration file.&lt;/li&gt;
&lt;li&gt;Important updates and bug fixes for Azure DevOps, see &lt;a href="https://github.com/qodo-ai/pr-agent/pull/1583" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Added support for adjusting the &lt;a href="https://qodo-merge-docs.qodo.ai/usage-guide/additional_configurations/#language-settings" rel="nofollow noopener noreferrer"&gt;response language&lt;/a&gt; of the PR-Agent tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Feb 6, 2025&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;New design for the &lt;code&gt;/improve&lt;/code&gt; tool:&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/21198860/410533969-26506430-550e-469a-adaa-af0a09b70c6d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDEzNDM0NDQsIm5iZiI6MTc0MTM0MzE0NCwicGF0aCI6Ii8yMTE5ODg2MC80MTA1MzM5NjktMjY1MDY0MzAtNTUwZS00NjlhLWFkYWEtYWYwYTA5YjcwYzZkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzA3VDEwMjU0NFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTU2MjExNzQzZDhjMGVjMzIwMTE0ZTNkZGJjN2ViNjM4MDliMThmNTkzN2RkNzQ5YmRjNWQzMWFhODA4ZTIxM2MmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.UviHjrDSxTIw0003WRLb52a_24yqxj4vv5DFlLz9oY8"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F21198860%2F410533969-26506430-550e-469a-adaa-af0a09b70c6d.png%3Fjwt%3DeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDEzNDM0NDQsIm5iZiI6MTc0MTM0MzE0NCwicGF0aCI6Ii8yMTE5ODg2MC80MTA1MzM5NjktMjY1MDY0MzAtNTUwZS00NjlhLWFkYWEtYWYwYTA5YjcwYzZkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAzMDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMzA3VDEwMjU0NFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTU2MjExNzQzZDhjMGVjMzIwMTE0ZTNkZGJjN2ViNjM4MDliMThmNTkzN2RkNzQ5YmRjNWQzMWFhODA4ZTIxM2MmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.UviHjrDSxTIw0003WRLb52a_24yqxj4vv5DFlLz9oY8" width="512"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Jan 25, 2025&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The open-source GitHub organization was updated:
&lt;code&gt;https://github.com/codium-ai/pr-agent&lt;/code&gt; →
&lt;code&gt;https://github.com/qodo-ai/pr-agent&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The docker should be redirected automatically to the new location
However, if…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/qodo-ai/pr-agent" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;describe&lt;/code&gt; command tool is a feature that automatically generates descriptions for pull requests (PRs) created. Users can manually invoke it by commenting "/describe" on a PR, or it can be set to trigger automatically when a new PR is opened. &lt;/p&gt;

&lt;p&gt;The configuration file for the tool includes options like &lt;code&gt;publish_labels&lt;/code&gt;, &lt;code&gt;publish_description_as_comment&lt;/code&gt;, &lt;code&gt;add_original_user_description&lt;/code&gt;, &lt;code&gt;keep_original_user_title&lt;/code&gt;, &lt;code&gt;extra_instructions&lt;/code&gt;, and &lt;code&gt;enable_pr_type&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Additionally, there is a markers template that allows users to integrate their content and auto-generated content through a template-like mechanism. Markers enable the replacement of specific content placeholders in the PR description, providing flexibility in structuring the output. Users can configure options such as &lt;code&gt;use_description_markers&lt;/code&gt; to enable the markers template and &lt;code&gt;include_generated_by_header&lt;/code&gt; to add a header indicating content generated by the PR Agent. Overall, the &lt;code&gt;describe&lt;/code&gt; tool streamlines the PR documentation process by automating the generation of comprehensive descriptions.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/wNGXpmeIYw8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  /review command:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/docs/REVIEW.md" rel="noopener noreferrer"&gt;https://github.com/Codium-ai/pr-agent/blob/main/docs/REVIEW.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;review&lt;/code&gt; tool scans the PR code changes, and automatically generates a PR review. It can be invoked manually by commenting on any PR.&lt;/p&gt;

&lt;p&gt;Users can manually invoke it by commenting "/review" on a PR, or it can be set to trigger automatically when a new PR is opened. The tool provides various configuration options under the 'pr_reviewer' section in the configuration file, allowing customization of features such as focused review, scoring, tests checking, security issue detection, and effort estimation.&lt;br&gt;
By adding a comment on your Pull Request, followed by a command, i.e:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@CodiumAI-Agent&lt;/code&gt; &lt;code&gt;/review&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You trigger CodiumAI PR-Agent to perform an action based on the command given, in this case, giving a review of the pull request.&lt;/p&gt;

&lt;p&gt;Additionally, the &lt;code&gt;review&lt;/code&gt; tool includes a PR reflection feature invoked by "/reflect_and_review." This feature prompts the author with questions about the PR, guiding the review based on their answers. A note on code suggestions quality emphasizes the potential for mistakes, encourages user judgment, and suggests using the 'extra_instructions' field to guide the model. It distinguishes between the general 'review' feature and the dedicated 'improve --extended' feature focused on suggestions.&lt;/p&gt;

&lt;p&gt;Overall, the &lt;code&gt;review&lt;/code&gt; tool streamlines the PR review process by automating various aspects and providing configurable options to adapt to project needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/achingachris/dad-jokes/pull/1" rel="noopener noreferrer"&gt;https://github.com/achingachris/dad-jokes/pull/1&lt;/a&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%2Flfh5zdr3uohkqly88y3i.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%2Flfh5zdr3uohkqly88y3i.png" alt="image" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  /improve Command
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/docs/IMPROVE.md" rel="noopener noreferrer"&gt;https://github.com/Codium-ai/pr-agent/blob/main/docs/IMPROVE.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;improve&lt;/code&gt; tool is a feature that automatically generates committable suggestions for enhancing code in pull requests (PRs). Users can manually trigger it by commenting "/improve" on a PR, and it can also be set to run automatically whenever a new PR is opened. An extended mode, activated by "/improve --extended," offers more comprehensive suggestions by dividing the PR code changes into chunks.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZcOYe5euk_8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  /ask Command
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/docs/ASK.md" rel="noopener noreferrer"&gt;https://github.com/Codium-ai/pr-agent/blob/main/docs/ASK.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ask&lt;/code&gt; tool is a feature designed to answer questions about a pull request (PR) based on the code changes in that PR. Users can manually trigger it by commenting "/ask" followed by a question in quotes on a PR.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;/ask "How do improve code quality"&lt;/code&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%2Fgz255y3j1srlwxri0uj1.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%2Fgz255y3j1srlwxri0uj1.png" alt="image" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  /similar_issue
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/docs/SIMILAR_ISSUE.md" rel="noopener noreferrer"&gt;https://github.com/Codium-ai/pr-agent/blob/main/docs/SIMILAR_ISSUE.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Similar Issue Tool&lt;/strong&gt; is a feature designed to retrieve the most similar issues to the current issue in a repository. Users can manually invoke this tool by commenting "/similar_issue" on any pull request (PR) or issue.&lt;/p&gt;

&lt;p&gt;The tool utilizes a retrieval system and indexes all previous issues in the repository to find and present similar issues. The retrieved information is then shared as comments in the respective PR or issue, providing users with relevant references or solutions.&lt;/p&gt;

&lt;p&gt;To enable the usage of the 'Similar Issue' tool, users need to set specific keys in the &lt;code&gt;.secrets.toml&lt;/code&gt; file or relevant environment variables. These parameters, including the Pinecone API key and environment, can be obtained by registering on the Pinecone platform.&lt;/p&gt;

&lt;p&gt;Overall, the 'Similar Issue Tool' aims to enhance issue resolution by providing users with references to similar issues in the repository, fostering collaboration and knowledge sharing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull Request Review Efficiency
&lt;/h2&gt;

&lt;p&gt;Now that we know what CodiumAI PR-Agent is capable of, let’s dive deep into how it enhances developer’s Pull Request efficiencies in comparison with GitHub Co-Pilot.&lt;/p&gt;

&lt;p&gt;A pull request (PR) review is an important stage of the software development lifecycle, ensuring that code changes are of high quality, meet coding requirements, and do not introduce bugs or security vulnerabilities. Both CodiumAI PR-Agent and GitHub Co-Pilot play significant roles in streamlining and enhancing the efficiency of pull request reviews.&lt;/p&gt;

&lt;h3&gt;
  
  
  CodiumAI PR-Agent's Approach to Pull Request Review
&lt;/h3&gt;

&lt;p&gt;CodiumAI PR-Agent takes a comprehensive approach to pull request reviews, incorporating several tools and features to analyze code changes, provide feedback, and assist developers in improving their code. Here are some key aspects of CodiumAI PR-Agent's pull request review efficiency:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auto Description:&lt;/strong&gt; &lt;br&gt;
The &lt;code&gt;/describe&lt;/code&gt; command automatically generates descriptive content for pull requests. This feature helps in creating comprehensive documentation, providing context about the changes made in the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auto Pull Request Review:&lt;/strong&gt; &lt;br&gt;
The &lt;code&gt;/review&lt;/code&gt; command scans the code changes in a pull request and generates an automatic review. This includes focused reviews, scoring, tests checking, security issue detection, and effort estimation. The tool provides configurable options to tailor the review process to the specific needs of the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PR Compression Strategy:&lt;/strong&gt; &lt;br&gt;
CodiumAI PR-Agent employs a unique PR compression strategy that effectively handles both short and long pull requests. This versatility ensures that the tool remains efficient in various code review scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modular and Customizable Tools:&lt;/strong&gt; &lt;br&gt;
The JSON prompting strategy allows for modularity and customization. Users can control tool categories and easily add new ones through the configuration file. This flexibility ensures that developers can adapt the tool to fit the requirements of their projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Broad Support and Flexibility:&lt;/strong&gt; &lt;br&gt;
CodiumAI PR-Agent supports multiple git providers, including GitHub, GitLab, Bitbucket, and CodeCommit. It offers multiple usage methods, such as CLI, GitHub Action, GitHub App, Docker, and more. Additionally, it supports multiple models, providing users with options to choose the underlying language model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open-Source Community:&lt;/strong&gt; &lt;br&gt;
Being an open-source project, CodiumAI PR-Agent encourages community contributions and collaboration. This open nature fosters continuous improvement and innovation.&lt;br&gt;
&lt;a href="https://github.com/Codium-ai/pr-agent" rel="noopener noreferrer"&gt;https://github.com/Codium-ai/pr-agent&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-World Practicality:&lt;/strong&gt; &lt;br&gt;
PR-Agent prioritizes practicality by limiting each tool to a single GPT-4 call, ensuring responsiveness (around 30 seconds) and cost-effectiveness for everyday team usage.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  GitHub Co-Pilot's Role in Pull Request Review
&lt;/h2&gt;

&lt;p&gt;GitHub Co-Pilot, on the other hand, primarily focuses on code completions, code generation, and code explanation. While it excels in assisting developers in writing better code by offering suggestions, its role in pull request reviews is not as direct as CodiumAI PR-Agent. However, it indirectly contributes to the overall efficiency of the development process by providing accurate and context-aware code suggestions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparative Analysis
&lt;/h2&gt;

&lt;p&gt;Now here is  a comparative analysis of CodiumAI PR-Agent and GitHub Co-Pilot concerning pull request review efficiency:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Focus on Pull Request Review:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodiumAI PR-Agent is designed to assist developers in the pull request review process, offering tools like &lt;code&gt;/review&lt;/code&gt; for automated reviews and feedback.&lt;/li&gt;
&lt;li&gt;GitHub Co-Pilot's primary focus is on code completion and generation, with less emphasis on providing detailed feedback for pull request reviews.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User Interface and Experience:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodiumAI PR-Agent’s UI/UX, integrated into IDEs like Visual Studio Code, enhances the user experience for managing and interacting with individual tests during pull request reviews.&lt;/li&gt;
&lt;li&gt;GitHub Co-Pilot, while excellent for code suggestions, may not provide the same level of testing-specific UI/UX, potentially making it less intuitive for pull request review tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing and Behavior Coverage:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodiumAI goes beyond generating tests by incorporating Behavior Coverage analysis and static code analysis techniques. This results in the creation of diverse test functions, contributing to the overall quality of the testing process.&lt;/li&gt;
&lt;li&gt;GitHub Co-Pilot may lack the same level of sophistication in terms of behavior coverage analysis, potentially limiting its effectiveness in ensuring comprehensive code testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Integration of Testing and Code Enhancement:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodiumAI PR-Agent allows developers to run generated tests and pull request commands within the IDE plugin(UI Interface in the IDE), facilitating a seamless experience for applying and reviewing fixes directly.&lt;/li&gt;
&lt;li&gt;GitHub Co-Pilot may not offer the same level of integration for testing and code enhancement within the development environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User-Friendly Interfaces:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodiumAI's emphasis on a user-friendly interface, specifically tailored for testing and pull request tasks, positions it as an intuitive and efficient choice for developers.&lt;/li&gt;
&lt;li&gt;GitHub Co-Pilot, while providing excellent code suggestions, may not have a specialized interface for pull request review tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Community Support and Open Source Nature:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodiumAI PR-Agent's open-source nature, coupled with its active community, ensures continuous improvement and adaptability to the evolving needs of developers.&lt;/li&gt;
&lt;li&gt;GitHub Co-Pilot, while a powerful tool, may have limitations in community-driven enhancements due to its closed-source nature.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;It is undeniable how Artificial Intelligence has made our lives easier, not just as developers, but humans in general, I mean look at what OpenAI is doing. In the midst of all these awesome and cool inventions that AI is doing, we are greate to have tools like CodiumAI PR-Agent, an AI tool specialized to handle Pull Requests straight from our IDEs and even on GitHub!&lt;/p&gt;

&lt;p&gt;Automating reviews, and minimizing development risks, have made CodiumAI PR-Agent a perfect go to tool. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>open</category>
      <category>javascript</category>
      <category>developer</category>
    </item>
    <item>
      <title>Setting Up a Django Project</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Wed, 06 Sep 2023 05:00:10 +0000</pubDate>
      <link>https://dev.to/chrisachinga/setting-up-a-django-project-c71</link>
      <guid>https://dev.to/chrisachinga/setting-up-a-django-project-c71</guid>
      <description>&lt;p&gt;&lt;a href="https://djangoproject.com/" rel="noopener noreferrer"&gt;Django&lt;/a&gt;(Python Django) is a high-level web development framework. It provides and flexible project structure and makes it easier to start new projects, In addition to that it follows the Model-View-Controller(MVC) architectural pattern, commonly referred to as Model-View-Template(MVT) in Django.&lt;/p&gt;

&lt;p&gt;In this piece, we will document the procedural steps to setting up and installing a Django project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;While there are a number of ways to get started, feel free to explore available options on the internet and go for whatever makes you comfortable.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before we get started, here is a checklist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; installed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.google.com/search?q=python+virtual+environment&amp;amp;oq=python+virt&amp;amp;gs_lcrp=EgZjaHJvbWUqBwgBEAAYgAQyBggAEEUYOTIHCAEQABiABDIHCAIQABiABDIHCAMQABiABDIHCAQQABiABDIHCAUQABiABDIHCAYQABiABDIGCAcQRRhB0gEINDM0OGowajeoAgCwAgA&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8" rel="noopener noreferrer"&gt;Virtual&lt;/a&gt; Environment (Recommended to have one): &lt;em&gt;I will be using virtualenv&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Creating a Virtual Environment(with &lt;code&gt;virtualenv&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;To get started, we will create a virtual environment to install and run Django. Using &lt;code&gt;virtualenv&lt;/code&gt; makes it way easier to do so(I think ... 🤔 💭).&lt;/p&gt;

&lt;p&gt;Open a terminal (CMD), and go to a working directory or a location where your project files will be. To create an environment, run the following:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Replace the  with the name of the project, i.e. My project will be: django-starter&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2Fahgwayabhrmlg4880exu.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%2Fahgwayabhrmlg4880exu.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that is done, you need to activate the environment. Before you do that, ensure that your terminal is in the project directory, "django-starter".&lt;/p&gt;

&lt;p&gt;To activate the environment, run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source bin/activate

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

&lt;/div&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%2Fo38ei4g6sh95b7plac3b.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%2Fo38ei4g6sh95b7plac3b.png" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the environment is activated, you will notice the environment will be enclosed by brackets on your terminal path:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(django-starter) chris@Chriss-MacBook-Pro django-starter %&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To install django, run the following on the terminal/CMD:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;To confirm a successful installation, you can use &lt;code&gt;pip freeze&lt;/code&gt; to check for installed packages inside the environment:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2Ffrh09j7ex4tz5w6ode1r.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%2Ffrh09j7ex4tz5w6ode1r.png" width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Django has the simplest project structure, you simply create a single django project, where you can have a number of applications inside it. We will start by creating a Django project, and then proceed to creating applications inside it.&lt;/p&gt;

&lt;p&gt;To create a project, run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django-admin startproject &amp;lt;project_name&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Replace the &lt;code&gt;&amp;lt;project_name&amp;gt;&lt;/code&gt; with the project name.&lt;/p&gt;

&lt;p&gt;Here's how I prefer to do it since I'm in the root folder of my environment, I'd love all my project configurations to be there, I will therefore run the following to create a django project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django-admin startproject config .

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

&lt;/div&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%2Ftfjl3o8x3z0jq6sfusz2.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%2Ftfjl3o8x3z0jq6sfusz2.png" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will create the core files to run and configure your project: &lt;code&gt;manage.py&lt;/code&gt; and a &lt;code&gt;config&lt;/code&gt; directory where it will have main settings and URLs for the project.&lt;/p&gt;

&lt;p&gt;Note that you wont be editing the &lt;code&gt;manage.py&lt;/code&gt; file. Inside the config directory, you will find a &lt;code&gt;settings.py&lt;/code&gt; file that defines the database, middleware, and more configurations for a Django project.&lt;/p&gt;

&lt;p&gt;(Optional Step)&lt;/p&gt;

&lt;p&gt;Before we run the server, open the settings.py and go to the TIME_ZONE variable. Set the timezone to your local time zone (Really helps with real-time logging and debugging)&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;I will update my timezone to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TIME_ZONE = 'Africa/Nairobi'

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

&lt;/div&gt;



&lt;p&gt;To test for a successful setup, start the server by running the following:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2Fee8petx45kjvcozxqirg.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%2Fee8petx45kjvcozxqirg.png" width="800" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Django locally runs on port 8000:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:8000/" rel="noopener noreferrer"&gt;http://localhost:8000/&lt;/a&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%2Fm3t2k24qmlw0da5du4vl.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%2Fm3t2k24qmlw0da5du4vl.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This confirms a successful setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This masterpiece has broken down the process of creating a Django project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Setting Up an Environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activating an Environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Installing Django&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating a Django Project&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: To deactivate the environment, run the following:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2Fs2klu0q5tr3rplcco2l7.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%2Fs2klu0q5tr3rplcco2l7.png" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Next?
&lt;/h3&gt;

&lt;p&gt;The next article will cover the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;How to create applications in a django project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to set Templates and Static files (CSS and JS)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing simple views and URLs&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Into PWA: Creating an installable Next.Js Application</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Sun, 25 Jun 2023 17:47:25 +0000</pubDate>
      <link>https://dev.to/chrisachinga/into-pwa-creating-an-installable-nextjs-application-5b9c</link>
      <guid>https://dev.to/chrisachinga/into-pwa-creating-an-installable-nextjs-application-5b9c</guid>
      <description>&lt;p&gt;Progressive Web Applications (PWAs) have gained significant popularity in recent years due to their ability to deliver a native-like experience to users across multiple devices. One of the frameworks that has emerged as a powerful tool for building PWAs is Next.js. &lt;/p&gt;

&lt;p&gt;Next.js, a React framework for server-side rendering, provides a solid foundation for creating fast and efficient web applications. In this article, we will explore the process of creating an installable Next.js application, taking advantage of the PWA features offered by modern browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Progressive Web Application (PWA)?
&lt;/h2&gt;

&lt;p&gt;A Progressive Web Application is a web application that utilizes modern web capabilities to deliver an app-like experience to users. PWAs are built with web technologies such as HTML, CSS, and JavaScript and can be accessed through a browser without installing an app store. PWAs offer several advantages, including offline functionality, push notifications, and the ability to be added to the user's home screen for quick access.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Z8MjdQGyjfA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a PWA with Next.Js
&lt;/h2&gt;

&lt;p&gt;Before diving into the process of creating an installable Next.js application, let's quickly set up a basic Next.js project. &lt;br&gt;
Ensure you have Node.js and npm (Node Package Manager) installed on your system. Then, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clone the Next.Js starter template (or create a new Next.Js application):&lt;br&gt;
&lt;code&gt;git clone https://github.com/achingachris/nextjs-starter.git&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the dependencies:&lt;br&gt;
&lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the installation completes, you can run the development server:&lt;br&gt;
&lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will start the Next.js development server, and your application will be accessible at &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&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%2Fzd6ol08tjv9on2zeff7r.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%2Fzd6ol08tjv9on2zeff7r.png" alt="Next.Js starter template" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding PWA Functionality: Installability
&lt;/h2&gt;

&lt;p&gt;For this demo, we will use an npm package, &lt;code&gt;[next-pwa](https://www.npmjs.com/package/next-pwa)&lt;/code&gt;, to install it, run the following at the root of the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i next-pwa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the installation is complete, update the &lt;code&gt;next.config.js&lt;/code&gt; file to have the following:&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;const&lt;/span&gt; &lt;span class="nx"&gt;withPWA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next-pwa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
      &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;skipWaiting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&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;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;reactStrictMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sassOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;includePaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;styles&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="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we added the &lt;code&gt;next-pwa&lt;/code&gt; configurations:&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;const&lt;/span&gt; &lt;span class="nx"&gt;withPWA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next-pwa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
      &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;skipWaiting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&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;The &lt;code&gt;withPWA&lt;/code&gt; function wraps the configuration options provided and returns a modified Next.js configuration object that includes the PWA settings. This modified configuration can be used in the &lt;code&gt;next.config.js&lt;/code&gt; file to enable the PWA features in your Next.js application.&lt;/p&gt;

&lt;p&gt;Using this code snippet, you can easily configure the &lt;code&gt;next-pwa&lt;/code&gt; package to add PWA functionality to your Next.js application, including service worker registration, caching, and offline support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the &lt;code&gt;manifest.json&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Next, create a new file in the root of your project called &lt;code&gt;public/manifest.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;manifest.json&lt;/code&gt; file is a key component of a Progressive Web Application (PWA). It provides metadata and configuration information about the application, allowing browsers and devices to understand and present the PWA appropriately. Here are the main functions of the &lt;code&gt;manifest.json&lt;/code&gt; file:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;App Metadata: The &lt;code&gt;manifest.json&lt;/code&gt; file contains information about the PWA, such as its name, short name, description, and icons. This metadata is used by browsers and devices when displaying the PWA, including on the home screen, app switcher, or other relevant user interfaces.&lt;/li&gt;
&lt;li&gt;Launch Behavior: The &lt;code&gt;manifest.json&lt;/code&gt; file defines the launch behavior of the PWA. For example, you can specify the start URL, which is the page the PWA opens when launched. You can also define the display mode, such as "fullscreen," "standalone," or "minimal-ui," which determines how the PWA appears to the user.&lt;/li&gt;
&lt;li&gt;Icons: The &lt;code&gt;manifest.json&lt;/code&gt; file allows you to specify icons of different sizes and formats for the PWA. Browsers and devices use these icons to represent the application visually. Providing icons in multiple sizes is important to ensure the PWA looks good on various devices and platforms.&lt;/li&gt;
&lt;li&gt;Theme Color: The &lt;code&gt;manifest.json&lt;/code&gt; file includes a theme color property that defines the color scheme for the PWA's user interface. Browsers can use this color to customize the appearance of the browser's UI elements when the PWA is active.&lt;/li&gt;
&lt;li&gt;Additional Configuration: The &lt;code&gt;manifest.json&lt;/code&gt; file can include other configuration options based on the specific requirements of the PWA. For example, you can define the orientation, background color, language preferences, and more.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Providing these details in the manifest.json file enables browsers and devices to handle the PWA appropriately, ensuring users' consistent and native-like experience. Additionally, the &lt;code&gt;manifest.json&lt;/code&gt; file is used when users choose to install the PWA, as it provides the necessary information for creating an app-like shortcut on the home screen and launching the PWA in its standalone mode.&lt;/p&gt;

&lt;p&gt;Here is a sample &lt;code&gt;manifest.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
        "name": "Next.js PWA Demo",
        "short_name": "pwaedemo",
        "description": "A Progressive Web App built with Next.js",
        "start_url": "/",
        "display": "standalone",
        "background_color": "#ffffff",
        "theme_color": "#000000",
        "icons": [
            {
                "src": "/icon-192x192.png",
                "sizes": "192x192",
                "type": "image/png"
            },
            {
                "src": "/icon-256x256.png",
                "sizes": "256x256",
                "type": "image/png"
            },
            {
                "src": "/icon-384x384.png",
                "sizes": "384x384",
                "type": "image/png"
            },
            {
                "src": "/icon-512x512.png",
                "sizes": "512x512",
                "type": "image/png"
            }
        ]
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find icons on the site &lt;a href="https://www.iconarchive.com/" rel="noopener noreferrer"&gt;https://www.iconarchive.com/&lt;/a&gt;, and customize the icons to various sizes on the site: &lt;a href="https://www.simicart.com/manifest-generator.html/" rel="noopener noreferrer"&gt;https://www.simicart.com/manifest-generator.html/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating &lt;code&gt;_document.js&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Finally, update the &lt;code&gt;_document.js&lt;/code&gt; file: &lt;code&gt;src/pages/_document.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"manifest"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/manifest.json"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"apple-touch-icon"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/icon-512x512.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"theme-color"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"#000"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complete file:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextScript&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Document&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="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;manifest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/manifest.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apple-touch-icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/icon-512x512.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&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;theme-color&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NextScript&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Html&lt;/span&gt;&lt;span class="err"&gt;&amp;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;
  
  
  Testing the Installable Next.js PWATesting the Installable Next.js PWA
&lt;/h2&gt;

&lt;p&gt;With the above configurations, you can now test your installable Next.js PWA. Run the following command in your project directory to build the optimized production version of your application:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`npm run build`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the build process completes, start the production server by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/MO4uAp087eY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;After installing the application, you can search it on the app launcher:&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%2Fulvxteg3rphxaa4p6o8d.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%2Fulvxteg3rphxaa4p6o8d.png" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In this article, we explored transforming a Next.js application into an installable Progressive Web Application (PWA). By leveraging the power of Next.js and the PWA capabilities provided by modern browsers, we can create fast, efficient, and app-like experiences for our users. Test your PWA on multiple devices and browsers to ensure broad compatibility and an optimal user experience. With the steps outlined in this article, you now have the knowledge to start building your own installable Next.js PWAs. Happy coding!&lt;/p&gt;

</description>
      <category>pwa</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Fetch Data from an API in Angular</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Mon, 29 May 2023 08:44:29 +0000</pubDate>
      <link>https://dev.to/chrisachinga/how-to-fetch-data-from-an-api-in-angular-4p37</link>
      <guid>https://dev.to/chrisachinga/how-to-fetch-data-from-an-api-in-angular-4p37</guid>
      <description>&lt;p&gt;&lt;em&gt;The Dad Jokes App: Spreading Laughter One Click at a Time&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This article will demonstrate how to get data from external APIs in an Angular project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Humor has a unique way of brightening up our day and creating moments of joy. In the digital age, countless apps cater to various interests, and one app that stands out is the Dad Jokes App. This lighthearted application brings a collection of witty and groan-inducing dad jokes to your fingertips, ensuring laughter is just a click away. &lt;br&gt;
In this article, we'll explore the features and development of the Dad Jokes App and its impact on users' daily lives.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;NodeJs Installed&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/start" rel="noopener noreferrer"&gt;Basic Angular Knowledge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Angular CLI installed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;NOTE:&lt;/em&gt;&lt;br&gt;
&lt;em&gt;The demo is using Tailwind CSS to get started with the starter, clone the repository:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://github.com/achingachris/dad-jokes-angular/tree/tailwindconfig&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating an Angular Project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://angular.io/start" rel="noopener noreferrer"&gt;To create an Angular project&lt;/a&gt;, be sure to have installed the Angular CLI on your local environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can learn more about the Angular CLI here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://angular.io/cli" rel="noopener noreferrer"&gt;https://angular.io/cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start a new Angular project, run the following script on a terminal (CMD):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    ng new dad-jokes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You will be prompted to select some choices for configurations. You can go with the defaults for this article.&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%2Fmx88poy8pz1byfxlp5ec.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%2Fmx88poy8pz1byfxlp5ec.png" alt="image" width="749" height="563"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Running Angular Locally
&lt;/h2&gt;

&lt;p&gt;Navigate to the project's root directory:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    &lt;span class="nb"&gt;cd &lt;/span&gt;dad-jokes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Run the following command to start the Angular development server:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffdbgh34e5hpz8vijrexw.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%2Ffdbgh34e5hpz8vijrexw.png" alt="image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open your browser and visit &lt;code&gt;**http://localhost:4200**&lt;/code&gt;. You should see the default Angular app running successfully.&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%2F5qhzrbwixvrvqvhgujue.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%2F5qhzrbwixvrvqvhgujue.png" alt="image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a Service:
&lt;/h2&gt;

&lt;p&gt;An Angular service class provides reusable functionality to your Angular application. Services typically handle data access, business logic, and other tasks not specific to a particular component.&lt;br&gt;
Services are defined using the &lt;code&gt;@Injectable()&lt;/code&gt; decorator, which tells Angular that the class can be injected into other classes as a dependency.  This allows you to easily share code and data between different parts of your application.&lt;/p&gt;

&lt;p&gt;This article will use an Angular service to get data from an API.&lt;/p&gt;

&lt;p&gt;To create a new service, run the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    ng generate service jokes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A new file will be created, &lt;code&gt;src/app/jokes.service.ts&lt;/code&gt;. Here, we will define the service to get data from an API.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&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;class&lt;/span&gt; &lt;span class="nc"&gt;JokesService&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="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;Update the code to request an HTTP API request and retrieve the jokes.&lt;br&gt;&lt;br&gt;
We will use the API: &lt;code&gt;https://icanhazdadjoke.com&lt;/code&gt; to fetch random “dad” jokes&lt;/p&gt;

&lt;p&gt;Here's an example implementation:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;providedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JokesService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://icanhazdadjoke.com&lt;/span&gt;&lt;span class="dl"&gt;'&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="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
      &lt;span class="nf"&gt;getJoke&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;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;http&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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="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 service is used to get jokes from the &lt;code&gt;icanhazdadjoke.com&lt;/code&gt; API. The &lt;code&gt;JokesService&lt;/code&gt; class is decorated with the &lt;code&gt;@Injectable()&lt;/code&gt; decorator, which tells Angular that the class can be injected into other classes as a dependency. This allows you to easily share code and data between different parts of your application.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;JokesService&lt;/code&gt; class has a single property, URL, and URL of the &lt;code&gt;icanhazdadjoke.com&lt;/code&gt; API. The class also has a constructor that takes an instance of the &lt;code&gt;HttpClient&lt;/code&gt; service as a dependency. The &lt;code&gt;HttpClient&lt;/code&gt; service is used to make HTTP requests to the &lt;code&gt;icanhazdadjoke.com&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;JokesService&lt;/code&gt; class has a single method, &lt;code&gt;getJoke()&lt;/code&gt;, which returns an &lt;code&gt;Observable&lt;/code&gt; of type &lt;code&gt;any&lt;/code&gt;. The &lt;code&gt;getJoke()&lt;/code&gt; method requests an HTTP to the &lt;code&gt;icanhazdadjoke.com&lt;/code&gt; API and returns an &lt;code&gt;Observable&lt;/code&gt; of the response data. The &lt;code&gt;Observable&lt;/code&gt; can be subscribed to in order to get the joke data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rendering Data:
&lt;/h2&gt;

&lt;p&gt;Now, let's render the fetched joke in our app's component. Open the &lt;code&gt;src/app.component.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Start by importing the JokesService:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    import &lt;span class="o"&gt;{&lt;/span&gt; JokesService &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'./jokes.service'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We then update the &lt;code&gt;AppComponent()&lt;/code&gt; class:&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;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dad jokes&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;jokeService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JokesService&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="nf"&gt;fetchJoke&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&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;jokeService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJoke&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;joke&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;joke&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Code explanations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;joke&lt;/code&gt; property is a string that will hold the joke that is fetched from the API.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;constructor&lt;/code&gt; method takes an instance of the &lt;code&gt;JokesService&lt;/code&gt; class as a dependency. The &lt;code&gt;JokesService&lt;/code&gt; class is used to fetch jokes from an API.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;fetchJoke()&lt;/code&gt; method calls the &lt;code&gt;getJoke()&lt;/code&gt; method on the &lt;code&gt;JokesService&lt;/code&gt; class and subscribes to the returned Observable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;fetchJoke()&lt;/code&gt; method is called when the application is loaded. The method calls the &lt;code&gt;getJoke()&lt;/code&gt; method on the &lt;code&gt;JokesService&lt;/code&gt; class. The &lt;code&gt;getJoke()&lt;/code&gt; method returns an &lt;code&gt;Observable&lt;/code&gt; of type &lt;code&gt;any&lt;/code&gt;. The &lt;code&gt;Observable&lt;/code&gt; emits an object that contains the joke data. The callback function passed to the &lt;code&gt;subscribe()&lt;/code&gt; method is called when the &lt;code&gt;Observable&lt;/code&gt; emits a value. The callback function sets the &lt;code&gt;joke&lt;/code&gt; property to the &lt;code&gt;joke&lt;/code&gt; property of the object that was emitted by the &lt;code&gt;Observable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The complete &lt;code&gt;src/app.component.ts&lt;/code&gt; file:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;JokesService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./jokes.service&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.css&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;joke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dad jokes&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;jokeService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JokesService&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="nf"&gt;fetchJoke&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&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;jokeService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJoke&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;joke&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;joke&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, we update our web view by opening the &lt;code&gt;**app.component.html**&lt;/code&gt; file. Update the file:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-blue-500 p-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container mx-auto flex items-center justify-between&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;href&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="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-xl font-bold text-white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Dad&lt;/span&gt; &lt;span class="nx"&gt;Jokes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/nav&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container mx-auto text-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mb-4 text-3xl font-bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Don&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;t Laugh Challenge&amp;lt;/h3&amp;gt;
      &amp;lt;div id="joke" class="mb-4 rounded-lg bg-gray-200 p-4"&amp;gt;{{ joke }}&amp;lt;/div&amp;gt;
      &amp;lt;button
        id="jokeBtn"
        class="rounded-lg bg-blue-500 px-4 py-2 text-white"
        (click)="fetchJoke()"
      &amp;gt;
        Get Another Joke
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Reload your browser to view the changes:&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%2Fh79u2zpruvtb2sl8nuco.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%2Fh79u2zpruvtb2sl8nuco.png" alt="image" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NOTE:&lt;br&gt;
The demo above used Tailwind CSS to get started with the starter, clone the repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/achingachris/dad-jokes-angular/tree/tailwindconfig" rel="noopener noreferrer"&gt;https://github.com/achingachris/dad-jokes-angular/tree/tailwindconfig&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complete source code is available on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/achingachris" rel="noopener noreferrer"&gt;
        achingachris
      &lt;/a&gt; / &lt;a href="https://github.com/achingachris/dad-jokes" rel="noopener noreferrer"&gt;
        dad-jokes
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Simple Angular App for Dad Jokes: Angular + Progressive web Apps using PWAFIRE
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Dad jokes&lt;/h1&gt;

&lt;/div&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/achingachris/dad-jokes" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


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

&lt;p&gt;In this article, we explored how to fetch data from an API using Angular. We covered the prerequisites, setting up an Angular project, fetching jokes from an API using a service, rendering the data in the app's component, and deploying the app on Vercel. With the app up and running, users can now enjoy a delightful collection of dad jokes, spreading laughter one click at a time.&lt;/p&gt;

&lt;p&gt;A live demo of the app can be view here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dad-jokes-angular.vercel.app/" rel="noopener noreferrer"&gt;https://dad-jokes-angular.vercel.app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>api</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Deploying A Django Project on PythonAnywhere</title>
      <dc:creator>c a</dc:creator>
      <pubDate>Tue, 23 May 2023 16:16:48 +0000</pubDate>
      <link>https://dev.to/chrisachinga/deploying-a-django-project-on-pythonanywhere-1jb3</link>
      <guid>https://dev.to/chrisachinga/deploying-a-django-project-on-pythonanywhere-1jb3</guid>
      <description>&lt;p&gt;Deploying a Django project on &lt;a href="https://pythonanywhere.com/" rel="noopener noreferrer"&gt;PythonAnywhere&lt;/a&gt; lets you make your web application accessible online. With PythonAnywhere, you can create a web app, configure it with a WSGI file, and host your Django project seamlessly.&lt;/p&gt;

&lt;p&gt;This article provides a comprehensive, step-by-step guide to help you deploy your existing Django project on PythonAnywhere successfully.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://pythonanywhere.com" rel="noopener noreferrer"&gt;Pythonanywhere&lt;/a&gt; Account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An existing Django project is ready for deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub (Code Repo)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic Familiarity with Django and the command line interface&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For demo purposes, please refer to the following project: Its a voting app from the official &lt;a href="https://docs.djangoproject.com/en/4.2/intro/tutorial01/" rel="noopener noreferrer"&gt;Django Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/achingachris/Django-Polls-Tutorials" rel="noopener noreferrer"&gt;https://github.com/achingachris/Django-Polls-Tutorials&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Uploading Your Code to pythonanywhere
&lt;/h2&gt;

&lt;p&gt;Open a console(terminal) on your pythonanywhere dashboard:&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%2Fu57izlvx08l6nifdnxhi.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%2Fu57izlvx08l6nifdnxhi.png" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just click on the blue bash button to open a terminal-like page:&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%2Fchbjv8ry22ekbijbs19s.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%2Fchbjv8ry22ekbijbs19s.png" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your Django project is hosted on a code-sharing platform like GitHub or Bitbucket, you can clone it directly onto PythonAnywhere using a Bash console. Here's an example command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/achingachris/Django-Polls-Tutorials.git

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

&lt;/div&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%2Fy084jbq6z560d8acqcaw.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%2Fy084jbq6z560d8acqcaw.png" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, as mentioned in the &lt;a href="https://help.pythonanywhere.com/pages/FileBrowser/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, you can explore other methods of uploading and downloading files on PythonAnywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set Up a Virtual Environment and Install Dependencies
&lt;/h2&gt;

&lt;p&gt;Create a virtual environment in the Bash console on PythonAnywhere and install Django and any other project dependencies.&lt;/p&gt;

&lt;p&gt;To do so, use the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; mkvirtualenv --python=/usr/bin/python3.10 &amp;lt;environment name&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;environment name&amp;gt;&lt;/code&gt; with any name, you want to give to your virtual environment.&lt;/p&gt;

&lt;p&gt;So for the demo, I will use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkvirtualenv --python=/usr/bin/python3.10 polls

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

&lt;/div&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%2Fdtt4e17f1gbnq84ryxzj.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%2Fdtt4e17f1gbnq84ryxzj.png" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To install the dependencies, change the active directive on your console to the folder cloned from GitHub(or uploaded):&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2Fez7yu9oz0fwhga6sy7bl.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%2Fez7yu9oz0fwhga6sy7bl.png" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure you have the &lt;code&gt;requirements.txt&lt;/code&gt; file&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%2F0paxyqru15ent07ineyw.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%2F0paxyqru15ent07ineyw.png" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To install the dependencies, run:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2F7ga3lj8cp3ehzvqk8jar.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%2F7ga3lj8cp3ehzvqk8jar.png" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure the Web App and WSGI File
&lt;/h2&gt;

&lt;p&gt;To set up your Django project on PythonAnywhere, follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Web app with Manual Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the "Web Apps" tab on PythonAnywhere and create a new web app.&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%2F0xhsstcxrf20edtry1sj.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%2F0xhsstcxrf20edtry1sj.png" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the default domain for free accounts&lt;/p&gt;

&lt;p&gt;Choose the "Manual Configuration" option and select the appropriate Python version matching your virtual environment.&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%2Flw4wewzjsrg8tjnunean.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%2Flw4wewzjsrg8tjnunean.png" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose a Python version: (preferably v3.10)&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%2F1ihlnxd0jgxoqdwpktly.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%2F1ihlnxd0jgxoqdwpktly.png" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will get notified that you have to set up the configuration manually:&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%2Fxmxg11qmh1k0grop4hq5.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%2Fxmxg11qmh1k0grop4hq5.png" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Specify the Virtual Environment:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to the "virtualenv" section of the web app configuration, and enter the name of your virtual environment (e.g., polls).&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%2Fgl32wmhq45jbakg5z52u.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%2Fgl32wmhq45jbakg5z52u.png" width="800" height="166"&gt;&lt;/a&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%2Fkoosglca6fax948jmx24.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%2Fkoosglca6fax948jmx24.png" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit the WSGI File:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to the Code section of the web app configuration.&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%2Fkarjj7fznxqbqahj2msx.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%2Fkarjj7fznxqbqahj2msx.png" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the link and make the necessary changes to the WSGI file. You will be redirected to an in-browser text editor view:&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%2F5pny1ox70g7plc1z9176.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%2F5pny1ox70g7plc1z9176.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Delete everything except the Django section and then uncomment that section. Your WSGI file should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# +++++++++++ DJANGO +++++++++++
    # To use your own Django app use code like this:
    import os
    import sys

    # assuming your Django settings file is at '/home/myusername/mysite/mysite/settings.py'
    path = '/home/myusername/mysite'
    if path not in sys.path:
        sys.path.insert(0, path)

    os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

    ## Uncomment the lines below depending on your Django version
    ###### then, for Django &amp;gt;=1.5:
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()
    ###### or, for older Django &amp;lt;=1.4
    #import django.core.handlers.wsgi
    #application = django.core.handlers.wsgi.WSGIHandler()

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

&lt;/div&gt;



&lt;p&gt;Edit the code to configure your Django application. For the demo, the project name is &lt;code&gt;polls&lt;/code&gt; , and my username is &lt;code&gt;chrisachinga&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

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

path = '/home/chrisachinga/polls'
   if path not in sys.path:
      sys.path.insert(0, path)

os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

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

&lt;/div&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%2Feulzqpsh0zo83higm6kv.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%2Feulzqpsh0zo83higm6kv.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember to save after editing the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will use the simple SQLite database for this demo, so no extra configuration is needed.&lt;/p&gt;

&lt;p&gt;Go to the &lt;strong&gt;Consoles tab&lt;/strong&gt; , start a bash console, and use &lt;code&gt;cd&lt;/code&gt; to navigate to the directory where your Django projects &lt;a href="http://manage.py" rel="noopener noreferrer"&gt;&lt;code&gt;manage.py&lt;/code&gt;&lt;/a&gt; lives, then run:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2F3g2gyp017bp9krafcou9.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%2F3g2gyp017bp9krafcou9.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(ignore the warnings 🤣🤣)&lt;/p&gt;

&lt;p&gt;You can now check if everything is okay. Click the link on the web tab to view the deployed version: &lt;a href="http://chrisachinga.pythonanywhere.com" rel="noopener noreferrer"&gt;&lt;em&gt;chrisachinga.pythonanywhere.com&lt;/em&gt;&lt;/a&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%2Fak3mch99hir3437jwk26.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%2Fak3mch99hir3437jwk26.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On loading the site, its most likely to get this error: &lt;code&gt;DisallowedHost&lt;/code&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%2Ffnaxwm49ns9jkmo2prlp.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%2Ffnaxwm49ns9jkmo2prlp.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how you can solve it:&lt;/p&gt;

&lt;p&gt;Open the Django settings file (&lt;code&gt;settings.py&lt;/code&gt;) in your project. Locate the &lt;code&gt;**ALLOWED_HOSTS**&lt;/code&gt; variable. It should be a list or tuple.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;'&lt;/code&gt;&lt;a href="http://chrisachinga.pythonanywhere.com" rel="noopener noreferrer"&gt;&lt;code&gt;chrisachinga.pythonanywhere.com&lt;/code&gt;&lt;/a&gt;&lt;code&gt;'&lt;/code&gt; to the list of allowed hosts. Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'chrisachinga.pythonanywhere.com']

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

&lt;/div&gt;



&lt;p&gt;I edited mine on GitHub:&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%2F8i83lfoexfv7jjmh8s1u.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%2F8i83lfoexfv7jjmh8s1u.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Include any other domains or IP addresses you want to allow access to your site.&lt;/p&gt;

&lt;p&gt;To update the code on pythonanywhere, you can pull the code from the terminal:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&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%2Favwoicaoadotcnc923rh.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%2Favwoicaoadotcnc923rh.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, head back to the web application tab and reload the site:&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%2Fonelatobvnf02ms6j0gz.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%2Fonelatobvnf02ms6j0gz.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now, when I load the site on: IT WORKS!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chrisachinga.pythonanywhere.com/polls/" rel="noopener noreferrer"&gt;https://chrisachinga.pythonanywhere.com/polls/&lt;/a&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%2Fd2mnwvtx4n2157dbexbn.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%2Fd2mnwvtx4n2157dbexbn.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can interact with the Django shell and API on the console to create a superuser, migrate databases, and more. Just ensure the virtualenv is turned on.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Following this step-by-step guide, you can successfully deploy your Django project on PythonAnywhere. Remember to adapt the instructions to match your project's specific configuration and requirements. PythonAnywhere offers a convenient platform for hosting your Django application, allowing you to share your web app with users across the internet. Enjoy the benefits of a live Django site hosted on PythonAnywhere and provide an exceptional user experience.&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
    </item>
  </channel>
</rss>
