<?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: Brian Oliver</title>
    <description>The latest articles on DEV Community by Brian Oliver (@brian101co).</description>
    <link>https://dev.to/brian101co</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%2F505205%2F990e2efd-5afb-4082-9dcb-f830908a9c82.jpeg</url>
      <title>DEV Community: Brian Oliver</title>
      <link>https://dev.to/brian101co</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brian101co"/>
    <language>en</language>
    <item>
      <title>Wagtail for Django Devs: Create a Developer Portfolio</title>
      <dc:creator>Brian Oliver</dc:creator>
      <pubDate>Mon, 30 Nov 2020 07:27:02 +0000</pubDate>
      <link>https://dev.to/brian101co/wagtail-for-django-devs-create-a-developer-portfolio-5e75</link>
      <guid>https://dev.to/brian101co/wagtail-for-django-devs-create-a-developer-portfolio-5e75</guid>
      <description>&lt;p&gt;Managing content isn’t easy, but that’s where Wagtail steps in. Wagtail is a Django CMS that makes managing your website’s content easy—even fun. It provides an intuitive admin interface with a rich set of features, such as streamfields and intelligent images, so producing and managing content is a charm.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will be building a developer portfolio using Wagtail and exploring the CMS’s ins and outs. The portfolio website we will be creating will have a homepage, portfolio page, and a blog where you can showcase your know-how.&lt;/p&gt;

&lt;p&gt;If this sounds like a cool project to you, then let’s jump straight in and start learning about the great things Wagtail has to offer us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup and Installing Wagtail
&lt;/h2&gt;

&lt;p&gt;First things first, we need to install Wagtail and set up our portfolio project. Let’s create the project folder we will work out of and change into that folder.&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;mkdir &lt;/span&gt;devport
&lt;span class="nb"&gt;cd &lt;/span&gt;devport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect that sets up our project’s working directory. Now we can move onto setting up the virtual environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Virtual Environment
&lt;/h2&gt;

&lt;p&gt;Creating a virtual environment for all your projects is a great habit to get into. They create a container or a walled garden around your project, so it doesn’t interfere with other projects on your machine. To create my virtual environment, I will be using pipenv.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;With that one command, pipenv creates a new virtual environment inside our project working directory. After running &lt;code&gt;pipenv install&lt;/code&gt;, you should see some output in your terminal, similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Creating a virtualenv &lt;span class="k"&gt;for &lt;/span&gt;this project…
Pipfile: /Users/brian/Documents/tutorials/devport/Pipfile
Using /Users/brian/.pyenv/versions/3.6.9/bin/python3.6m &lt;span class="o"&gt;(&lt;/span&gt;3.6.9&lt;span class="o"&gt;)&lt;/span&gt; to create virtualenv…
⠴ Creating virtual environment...created virtual environment CPython3.6.9.final.0-64 &lt;span class="k"&gt;in &lt;/span&gt;307ms
  creator CPython3Posix&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/Users/brian/.local/share/virtualenvs/devport-fsisFtpz, &lt;span class="nv"&gt;clear&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False, &lt;span class="nv"&gt;global&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False&lt;span class="o"&gt;)&lt;/span&gt;
  seeder FromAppData&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False, &lt;span class="nv"&gt;pip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundle, &lt;span class="nv"&gt;setuptools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundle, &lt;span class="nv"&gt;wheel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundle, &lt;span class="nv"&gt;via&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;copy, &lt;span class="nv"&gt;app_data_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/Users/brian/Library/Application Support/virtualenv&lt;span class="o"&gt;)&lt;/span&gt;
    added seed packages: &lt;span class="nv"&gt;pip&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;20.2.2, &lt;span class="nv"&gt;setuptools&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;49.6.0, &lt;span class="nv"&gt;wheel&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;0.35.1
  activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

 Successfully created virtual environment! 
Virtualenv location: /Users/brian/.local/share/virtualenvs/devport-fsisFtpz
Installing dependencies from Pipfile.lock &lt;span class="o"&gt;(&lt;/span&gt;ca72e7&lt;span class="o"&gt;)&lt;/span&gt;…
     ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To activate this project's virtualenv, run &lt;code&gt;pipenv shell&lt;/code&gt;.&lt;br&gt;
Alternatively, run a command inside the virtualenv with &lt;code&gt;pipenv run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Command not recognized? Run &lt;code&gt;pip install pipenv&lt;/code&gt; to install the package. After it has been successfully installed, rerun the &lt;code&gt;pipenv install&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;To activate the virtual environment, we run the command &lt;code&gt;pipenv shell&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipenv shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the virtual environment is activated, a set of parentheses surrounding the project folder’s name should appear on the left in your terminal. In my case, &lt;code&gt;(devport)&lt;/code&gt; appears on my terminal’s lefthand side when the virtual environment is activated. To exit the virtual environment, run the command &lt;code&gt;exit&lt;/code&gt;. As we saw before, to start it run the &lt;code&gt;pipenv shell&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;After creating the virtual environment, you should see two new files created inside your project working directory: &lt;code&gt;Pipfile&lt;/code&gt; and &lt;code&gt;Pipfile.lock&lt;/code&gt;. These files manage your project’s dependencies, much like how npm makes a package.json file to manage dependencies. Each new package we install gets added to the &lt;code&gt;Pipfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the virtual environment set up, we are ready to install Wagtail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Wagtail
&lt;/h2&gt;

&lt;p&gt;To install Wagtail, run the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This command installs Wagtail and its dependencies. Inside our project’s working directory, let’s start a new Wagtail project by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wagtail start devportfolio &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Provided by Wagtail, the &lt;code&gt;start&lt;/code&gt; command is similar to Django’s &lt;code&gt;django-admin startproject&lt;/code&gt; command. The &lt;code&gt;start&lt;/code&gt; command generates a project folder, devportfolio in my case, containing the project’s settings, a home app including a blank homepage model, and a sample search app.&lt;/p&gt;

&lt;p&gt;Notice the start command created a &lt;code&gt;requirements.txt&lt;/code&gt; file in our project working directory. This file functions similarly to how the &lt;code&gt;Pipfile&lt;/code&gt; works by keeping track of project dependencies. Inside the &lt;code&gt;requirements.txt&lt;/code&gt; file are all the dependencies Wagtail needs to run, so we will tell pipenv to install any dependency in this file if it’s not already installed by running the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Before we can check out our new Wagtail site in the browser, we first have to create the database by running the initial migrations. To generate our database, run the following command:&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 migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a long list of applied migrations in your terminal. These are the names of the created tables in your database. After the migrations have finished, start the development server by running the following command:&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 runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can navigate over to &lt;code&gt;localhost:8000&lt;/code&gt; and check out our new Wagtail site in the browser. You should see the default Wagtail landing page come up. Pretty cool!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LAZ1IsOc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c6gdiptzgx906udjpwcc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LAZ1IsOc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c6gdiptzgx906udjpwcc.png" alt="Screenshot of the Wagtail default welcome page"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;To begin exploring the Wagtail admin, we first need to create a superuser by running the following command:&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 createsuperuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts in the terminal to create your superuser. After you set up your superuser, restart the development server, and navigate to &lt;code&gt;localhost:8000/admin/&lt;/code&gt; to login into the Wagtail admin.&lt;/p&gt;

&lt;p&gt;Your screen should look similar to this after logging in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S_EYK8WA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1v9t7ynxx41qjjpcu5c7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S_EYK8WA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1v9t7ynxx41qjjpcu5c7.png" alt="Screenshot of Wagtail admin dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the Wagtail dashboard, a central hub for all your site’s information. At a glance, the dashboard provides information on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the number of pages, images, and documents currently held in the Wagtail CMS.&lt;/li&gt;
&lt;li&gt;Any pages now awaiting moderation (if you have these privileges).&lt;/li&gt;
&lt;li&gt;Your most recently edited pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We only have one page; however, we will create more pages later in the tutorial. Let’s keep exploring the Wagtail admin before diving deeper into the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Editing Pages in the Wagtail Admin
&lt;/h2&gt;

&lt;p&gt;In the Wagtail admin, you can edit the default home page by clicking the page tab in the sidebar, then clicking the edit icon on the homepage that pops up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0e8nuOYw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mgwmncj9rnptdiw12f2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0e8nuOYw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mgwmncj9rnptdiw12f2l.png" alt="Screenshot of the home page admin editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see the editing interface come up, like in the screenshot above. Let’s change the page’s title. I’m going to change the title to “Dev Portfolio.” Feel free to change the title to whatever you would like. After changing the title, click the “^” icon at the bottom of the page, then click publish. The changes are now live. Let’s check out the updated page by clicking “VIEW LIVE” in the top banner to view the live page.&lt;/p&gt;

&lt;p&gt;Sweet, you should see the default Wagtail landing page again, but notice the browser tab’s title has changed. Pretty cool! That’s how we can make edits and manage Wagtail pages. In the next tutorial, we will flesh out the homepage with a lot more content.&lt;/p&gt;

&lt;p&gt;If you would like to read the other tutorials in the series, check out my blog &lt;a href="https://engineertodeveloper.com/category/wagtail/"&gt;EngineerToDeveloper&lt;/a&gt; for more free tutorials like this.&lt;/p&gt;

&lt;p&gt;I hope you all enjoyed the tutorial. If you have any questions, leave a comment below, and I will do my best to help out!&lt;/p&gt;

</description>
      <category>django</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Return a JSON Response in Django</title>
      <dc:creator>Brian Oliver</dc:creator>
      <pubDate>Mon, 09 Nov 2020 08:30:42 +0000</pubDate>
      <link>https://dev.to/brian101co/how-to-return-a-json-response-in-django-gen</link>
      <guid>https://dev.to/brian101co/how-to-return-a-json-response-in-django-gen</guid>
      <description>&lt;h2&gt;
  
  
  What is JSON?
&lt;/h2&gt;

&lt;p&gt;JSON stands for JavaScript Object Notation and is a common and lightweight data format returned from APIs. One of the main benefits of JSON is its easy readability for developers and workability using JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"car"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Protecting API keys
&lt;/h2&gt;

&lt;p&gt;A common use case as to why we might want to return a JSON response in Django is to protect API keys. Client-side JavaScript is directly editable in the developer tools, while code on the server isn't accessible to the client.&lt;/p&gt;

&lt;p&gt;Malicious people may steal your API key and start using the service under your account, so you will be charged for all the API usage, ending up with hundreds or thousands of lost dollars depending on the usage volume. &lt;/p&gt;

&lt;h2&gt;
  
  
  Returning a JSON Response from an API
&lt;/h2&gt;

&lt;p&gt;Django provides a built-in class JsonResponse that makes returning JSON easy.  By default, the JsonResponse class sets a Content-Type header of application/json. &lt;/p&gt;

&lt;p&gt;Let's make an API call to the &lt;a href="https://www.thecocktaildb.com/"&gt;CocktailDB API&lt;/a&gt; that will return a list of cocktails and their ingredients to pass on as a JsonResponse to our frontend.&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;# views.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;JsonResponse&lt;/span&gt;

&lt;span class="c1"&gt;# In production, this should be set as an environment variable
&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cocktail_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;f"https://www.thecocktaildb.com/api/json/v1/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/search.php?s=margarita"&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;JsonResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we import the requests library to make an HTTP GET request to the CoctailDB endpoint to get a list of all the margarita drinks. If you don't have requests already installed, you can install it by running pip install requests. Then we import the JsonResponse class to return the margaritas as JSON.&lt;/p&gt;

&lt;p&gt;We call .json() on the response, we get back to convert it into a JSON object and pass that to our JsonResponse(), which will return it to our client.&lt;/p&gt;

&lt;p&gt;We can verify that we have a list of margaritas in JSON by wiring up the view in our urls.py and accessing the URL in our browser. You should see a list of JSON objects.&lt;/p&gt;

&lt;p&gt;By default, the first parameter in the JsonResponse class is &lt;em&gt;data&lt;/em&gt; that accepts an instance of dict.  If you pass data that isn't a dictionary, you will have to set the safe parameter to False.&lt;/p&gt;

&lt;p&gt;Let's say you want to return a list of dictionaries. Since the list isn't an instance of dict, we will have to set safe=False.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"car"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Joel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"car"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;JsonResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;safe&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Returning a JSON response from a Django Model.
&lt;/h2&gt;

&lt;p&gt;To return a queryset of python object as JSON, we first have to convert it into a Python dictionary. The process of converting one data type to another is called serialization.&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;# views.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.serializers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;django_models_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'content'&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;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We import the serialize function. This function accepts the following parameters: format, queryset, and an optional fields parameter.&lt;/p&gt;

&lt;p&gt;In the example, above our format is "json". Our queryset is qs, which are all the posts objects in the database, and we specified only to return the title and content fields from the model.&lt;/p&gt;

&lt;p&gt;Why did I use an HttpResponse here instead of JsonResponse? The JsonResponse class takes a second parameter encoder, which is set to DjangoJSONEncoder by default. This encoder converts our data to JSON. So if we pass JSON to our JsonResponse class, it will encode it again, causing our JSON output to contain backslashes due to double serialization.&lt;/p&gt;

&lt;p&gt;Conversely, the HttpResponse class does not have an encoder. So when we pass our already serialized JSON to it, it does not serialize it again. &lt;/p&gt;

&lt;p&gt;If we wire up the view and test it out in the browser, we will see our model objects returned to us in JSON format.&lt;/p&gt;

&lt;p&gt;If you would like to return a JSON response of a single model object, we would do it 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="c1"&gt;# views.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.serializers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;django_models_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'content'&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;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of passing in a queryset, we pass in a single object wrapped in a list so that the output will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Super Cool Title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Some really cool content"&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The object doesn't have to be wrapped in a list. If we passed the object not wrapped in a list, we would get an output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Super Cool Title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"Some really cool content"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you guys enjoyed the tutorial and found it useful. If you have any questions, let me know in the comments, and I will try my best to answer them.&lt;/p&gt;

&lt;p&gt;For more tutorials like this one, check out my blog &lt;a href=""&gt;EngineerToDeveloper&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>In-Depth Guide to Deploying a Django Project to PythonAnywhere.</title>
      <dc:creator>Brian Oliver</dc:creator>
      <pubDate>Mon, 02 Nov 2020 21:48:37 +0000</pubDate>
      <link>https://dev.to/brian101co/in-depth-guide-to-deploying-a-django-project-to-pythonanywhere-2od6</link>
      <guid>https://dev.to/brian101co/in-depth-guide-to-deploying-a-django-project-to-pythonanywhere-2od6</guid>
      <description>&lt;p&gt;When I was first starting with Django, one of the most challenging obstacles I faced was deploying my application. In this tutorial, I will show you guys how to deploy your Django applications to PythonAnywhere and hopefully help you avoid the pitfalls I made.&lt;/p&gt;

&lt;p&gt;PythonAnywhere is a cloud-based hosting provider where you can deploy your Django project. The best part is that it’s free to get started, and you can upgrade anytime you are ready.&lt;/p&gt;

&lt;p&gt;One of the things I liked most about PythonAnywhere is that it comes with a Python environment already set up for you, making deploying your project easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Our Github Repository
&lt;/h2&gt;

&lt;p&gt;The first thing we will do is get our project ready for Github. Login to your Github account and click the new button to create a new repository. Fill out the info and click create. Once you have that setup, we need to get the project connected to your Github using Git.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H4snp8cU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tmepx83l9zs9m8yzrw1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H4snp8cU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tmepx83l9zs9m8yzrw1j.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you set up the repository, it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVyV9vnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7qyxztwvo09ampdzxftl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVyV9vnW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7qyxztwvo09ampdzxftl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Initializing Your Git Repository
&lt;/h2&gt;

&lt;p&gt;Let’s switch gears for a second. We will come back to Github in just a moment. Inside of your project working directory on your machine, that is your Django projects folder, so the one that contains your manage.py file, run git init. This will initialize a new git repository for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Our .gitignore File
&lt;/h2&gt;

&lt;p&gt;Before we continue, we need to create a file in our project directory called .gitignore. This file is used to tell git what files and folders to ignore. We don’t want to put our db.sqlite database in our Github repository since our production environment will have its database.&lt;/p&gt;

&lt;p&gt;Create the .gitignore using the touch command for Mac and Linux. If you are using Windows, you will have to use your text editor or file explorer to create the file.&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;touch&lt;/span&gt; .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it’s created, open the file and add the following folders and files to your .gitignore.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*.log
*.pot
*.pyc
__pycache__/
db.sqlite3
db.sqlite3-journal
media
static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are telling Git to ignore the development database, our static files, and our media files.&lt;/p&gt;

&lt;p&gt;Unsure of which files and folders to include in your .gitignore file? No worries, check out &lt;a href="https://www.toptal.com/developers/gitignore"&gt;gitignore.io&lt;/a&gt; for a list of files and folders you might want to add to your .gitignore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gathering Project dependencies with Requirements.txt
&lt;/h2&gt;

&lt;p&gt;Next, we will create a requirements.txt file. If you have worked with Node and Express before, this is similar to your package.json file. The requirements.txt file lists all the dependencies your project needs to run properly. This file is handy to keep track of what your project needs. We will see this in action later, where it will become more clear.&lt;/p&gt;

&lt;p&gt;Inside of your project directory, run the following terminal command to create your requirements.txt file.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connecting Our Git Repository to Github
&lt;/h2&gt;

&lt;p&gt;Now that our project is ready for Github, let’s make our first commit and set the branch to main. Making a commit in Git is like putting all the changes you made in your code inside a box and attaching a label to it so the “mailman” or git can deliver it to Github.&lt;/p&gt;

&lt;p&gt;Then we set the origin to our Github repository. We’re basically telling Git or our “mailman” where to deliver our code package too. After we set the origin or “address,” we push our code up to Github. For the sake of our mailman analogy, this would be equivalent to raising the red flag on our mailbox so the mailman can come to take our package to its destination.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"first commit."&lt;/span&gt;
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git remote add origin https://github.com/&amp;lt;your_github_username&amp;gt;/&amp;lt;your_project&amp;gt;.git
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git and Github Development Workflow
&lt;/h2&gt;

&lt;p&gt;From this point forward, our workflow will follow this pattern: &lt;strong&gt;develop and make changes locally&lt;/strong&gt; =&amp;gt; &lt;strong&gt;Push code to GitHub&lt;/strong&gt; =&amp;gt; &lt;strong&gt;Pull changes into our production environment&lt;/strong&gt;. This pattern will give us a smooth development cycle and keep all our code in sync with each other.&lt;/p&gt;

&lt;p&gt;Making changes and developing on the server is a bad idea because you might make breaking changes causing your site to go down. Also, your development environment will be out of sync with your production environment.&lt;/p&gt;

&lt;p&gt;If that was your first time setting up Git and Github, don’t worry. It can be unclear at first, but it makes more sense after the second and third time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up PythonAnywhere Account
&lt;/h2&gt;

&lt;p&gt;Now that our Github repository is set up, we need to make a pythonanywhere account to start deploying our Django project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I0JdTNM9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5topkykvsfjsr21g5k1m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I0JdTNM9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5topkykvsfjsr21g5k1m.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to the top right-hand corner and click signup/pricing; then click the “create a beginner account” button and fill in the information. Once that is set up, we can move on to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating PythonAnywhere Web App
&lt;/h2&gt;

&lt;p&gt;After setting up your account, click on the web tab, and then on the left-hand side, click “add a new web app.”&lt;/p&gt;

&lt;p&gt;Select manual configuration from the options. The Django option will install Django 2.2 for you, I believe. Since we already have a specific Django version we are working with, we will choose the manual configuration. Click next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8bWI44r_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f5il2szof3wpeoyfoyyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8bWI44r_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f5il2szof3wpeoyfoyyb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the version of Python you are using. I chose version 3.8. Click next and next again. Alright, now we have our web app setup. You should see a screen like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2mltP7Z1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t8cccd8x9kuwm13vuqqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2mltP7Z1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t8cccd8x9kuwm13vuqqb.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don’t worry about the extra tabs I have on the left. Those are other web apps I have running. If you deploy another web app, it will be displayed on the left. Alright, we’re getting closer to having our Django project deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bash Console
&lt;/h2&gt;

&lt;p&gt;Select the Dashboard tab and click on the bash console on the left-hand side. It doesn’t matter which bash console you select if there is more than one option. The bash console is a Linux terminal. The rest of this guide will be working mostly in this terminal and configuring our web tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Virtual Environment
&lt;/h2&gt;

&lt;p&gt;Creating a virtual environment for our Django project will allow us to deploy future projects on the same server without them interfering with each other.&lt;/p&gt;

&lt;p&gt;For example, one project might require Django 3.1 and the other Django 2.2. If we didn’t have a virtual environment created, that would cause issues trying to run different versions on the same server. Virtual environments create containers or little walled gardens for our projects to run in, so they don’t interfere with each other.&lt;/p&gt;

&lt;p&gt;Inside of your bash console, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkvirtualenv myprojectvenv &lt;span class="nt"&gt;--python&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/python3.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command mkvirtualenv will create a virtual environment called myprojectvenv. Specifying the –python flag on the mkvirtualenv command will set the python version for that environment. So you could have different virtualenvs running different versions of python—something we couldn’t do without a virtualenv. Your virtual environments are stored in the .virtualenvs directory in the home directory.&lt;/p&gt;

&lt;p&gt;You should see something like this in your console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Running virtualenv with interpreter /usr/bin/python3.8
Using base prefix &lt;span class="s1"&gt;'/usr'&lt;/span&gt;
New python executable &lt;span class="k"&gt;in&lt;/span&gt; /home/myusername/.virtualenvs/myprojectvenv/bin/python3.8
Also creating executable &lt;span class="k"&gt;in&lt;/span&gt; /home/myusername/.virtualenvs/myprojectvenv/bin/python
Installing setuptools, pip, wheel...done.
virtualenvwrapper.user_scripts creating /home/myusername/.virtualenvs/myprojectvenv/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/myusername/.virtualenvs/myprojectvenv/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/myusername/.virtualenvs/myprojectvenv/bin/preactivate
virtualenvwrapper.user_scripts creating /home/myusername/.virtualenvs/myprojectvenv/bin/postactivate
virtualenvwrapper.user_scripts creating /home/myusername/.virtualenvs/myprojectvenv/bin/get_env_details

&lt;span class="o"&gt;(&lt;/span&gt;myprojectvenv&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;which python
/home/myusername/.virtualenvs/myvirtualenv/bin/python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the virtual environment is activated, you will see parentheses with the name of your virtual environment on the left in your console. Whenever this is present, we are in our virtual environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting Our Virtual Environment with Our Web App
&lt;/h3&gt;

&lt;p&gt;We need to let pythonanywhere know where to find our virtual environment. So let’s get the working directory for that. Cd into your virtual environment directory like so:&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; .virtualenvs
&lt;span class="nb"&gt;pwd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After we cd into the virtual environment directory from our home directory, we run pwd to get the working directory. Copy that path and go back to the web tab in pythonanywhere and under the section, virtualenvs paste in the path, then add the name of your virtual environment to the end.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NIup7Pmh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rf67pemioi4039dbx7wo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NIup7Pmh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rf67pemioi4039dbx7wo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need to exit the virtual environment, run deactivate in the console. When you are ready to work on the project again, you can start your virtual environment back up by running workon myprojectvenv.&lt;/p&gt;

&lt;p&gt;If you would like to know more about how the virtual environments work in PythonAnywhere, check out their article &lt;a href="https://help.pythonanywhere.com/pages/Virtualenvs/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloning our Project to PythonAnywhere
&lt;/h2&gt;

&lt;p&gt;With our virtual environment set up, we can clone our project from Github and start setting it up.&lt;/p&gt;

&lt;p&gt;Go to your Github repository, click on the green code button, and copy your Github repository link. In your bash console, run the following to clone your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/&amp;lt;username&amp;gt;/&amp;lt;repository&amp;gt;.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command downloads all the code from your repository to your PythonAnywhere server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Project Requirements
&lt;/h2&gt;

&lt;p&gt;Let’s cd into our project directory, the directory with manage.py in it, and install our project requirements. This is where our requirements.txt file shines. Run the following command in your bash console.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TIP:&lt;/strong&gt; Run ls in your console to list out all the files and directories to see which one you need to cd into.&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;myproject
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pip will read the requirements.txt file and install all the packages our project requires to run. Sweet, let’s wait for that to install. It may take a moment.&lt;/p&gt;

&lt;p&gt;Now that our requirements are installed let’s configure our source directory real quick.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Web App Directories
&lt;/h2&gt;

&lt;p&gt;The source directory lets pythonanywhere know where our project’s code lives. Run pwd in the console to get your project working directory. Copy it, go back to the web tab, and in the Code section, you should see two file paths listed out—one for Source code and the other for project working directory. Paste in the project working directory you copied for both source and working directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pE3TXCJJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i9r0x8kcuvn8k46ygt44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pE3TXCJJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i9r0x8kcuvn8k46ygt44.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Static and Media Files
&lt;/h2&gt;

&lt;p&gt;After all our packages are installed, we can collect our static files. &lt;strong&gt;Django will store all your static assets in the directory name you specified in your STATIC_ROOT setting.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your bash console to collect your static files.&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 collectstatic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, select yes.&lt;/p&gt;

&lt;p&gt;Sweet, now let’s tell PythonAnywhere where it can find our static files. Cd into your newly generated statics directory or whichever name you chose and run pwd in the console. This will print out your current working directory. Copy the path and go to your project’s web tab in PythonAnywhere.&lt;/p&gt;

&lt;p&gt;Scroll down some, and you should see a section called static files. Paste the file path into the directory box. Then set the URL box to /static/ or the folder name you specified in your settings.py. It should look similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AHCRN3LS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2duwzcqdbhsckk02jqzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AHCRN3LS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2duwzcqdbhsckk02jqzz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are storing user-generated media files in a media folder, go ahead and add that as shown in the image above.&lt;/p&gt;

&lt;p&gt;This isn’t the best way to store user-uploaded media. I will write another tutorial on how to store user uploaded media using AWS S3 or DropBox later. We will serve our media files from our Django application for this tutorial but keep in mind this isn’t ideal.&lt;/p&gt;

&lt;p&gt;The same applies to our static assets. It’s best to have a web server such as NGINX or a CDN serve the static assets. I will write another tutorial looking into these solutions later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adjusting Our Settings for Production
&lt;/h2&gt;

&lt;p&gt;We’re getting close to the end now. If you have followed along with the tutorial this far, we are just about finished.&lt;/p&gt;

&lt;p&gt;Go to the web tab, and under the section code, click on “go to directory.” From there, navigate to your project’s settings.py file. Click on the file. This should open up an editor in the browser so you can make changes to the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Change the DEBUG setting to False.&lt;/strong&gt; We set this too False so that debugging information isn’t sent to the browser but instead sends a 404 error. The debug message sends essential information about our project’s structure that hackers can take advantage of if they knew.&lt;/p&gt;

&lt;p&gt;Next, add your free pythonanywhere domain name to your ALLOWED_HOSTS list. Make sure quotes surround it. It has to be a string. This setting is a list of strings representing the host/domain names that this Django site can serve. This is a security measure to prevent HTTP Host header attacks, possibly even under many seemingly-safe web server configurations.&lt;/p&gt;

&lt;p&gt;Save the file and go back to the web tab and click the reload button at the top. This will take a second. This will load the new settings that we changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTPS with Let’s Encrypt
&lt;/h2&gt;

&lt;p&gt;Next, we need to make sure our site uses HTTPS. There is almost no reason to use HTTP anymore. HTTPS encrypts all the information sent to and from our website and protects our visitors.&lt;/p&gt;

&lt;p&gt;In the web tab under the Security section near the bottom, click on the HTTPS certificate’s pencil icon. Select the Let’s Encrypt option and save. This creates a valid SSL certificate from Let’s Encrypt. The best part is that PythonAnywhere takes care of the renewal process, so you don’t have to worry about renewing it before it expires.&lt;/p&gt;

&lt;p&gt;Enable Forced HTTPS. Now let’s go back to the top of the page and reload our website.&lt;/p&gt;

&lt;p&gt;Alright, that takes care of HTTPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Variables with .env File
&lt;/h2&gt;

&lt;p&gt;In this section, we will address our SECRET_KEY issue. This key must be hidden because it is used to provide cryptographic signing and having it in plain text is a security risk.&lt;/p&gt;

&lt;p&gt;Back inside your project directory in the bash console, we need to create a .env file at the same level as the manage.py file.&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;touch&lt;/span&gt; .env
nano .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside of the terminal editor, add your secret key like below:&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;export &lt;/span&gt;&lt;span class="nv"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"mysupersupersecretkey"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then press control+x then y then enter/return. That saves our .env file with our secret key added to it.&lt;/p&gt;

&lt;p&gt;Next, we need to install dotenv so we can use our environment variable file.&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;python-dotenv
&lt;span class="nb"&gt;echo &lt;/span&gt;python-dotenv &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This installs dotenv and adds it to our requirements.txt file.&lt;/p&gt;

&lt;p&gt;Now we need to edit our WSGI file. Let’s go back to the web tab, and under the code section, you should see the WSGI configuration file below the source and working directory. Click on it to open it up.&lt;/p&gt;

&lt;p&gt;Delete everything from the WSGI file except the Django section. It should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bTaCdSbv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/doihro72s1f15pv0nx56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bTaCdSbv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/doihro72s1f15pv0nx56.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to set the path variable in your WSGI file to your project working directory and change your DJANGO_SETTINGS_MODULE from mysite.settings to the app your project’s settings.py file is under. For example, my settings.py file is under my portfolio app, so I put portfolio.settings.&lt;/p&gt;

&lt;p&gt;Right beneath the imports, add this to your WSGI file:&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="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="n"&gt;project_folder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expanduser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'~/your-project-dir'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project_folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'.env'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This loads our .env file so our Django project can access the environment variables we have set in it. Make sure to replace your-project-dir with your project’s working directory (the one that contains manage.py). Save your WSGI file.&lt;/p&gt;

&lt;p&gt;Now we need to remove our secret key from our settings.py and load in our environment variable. Let’s navigate back to our settings.py files and change our SECRET_KEY to 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;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SECRET_KEY"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save your settings.py file.&lt;/p&gt;

&lt;p&gt;Next, let’s load our .env variables into our bash console. Inside your bash console, run the following commands:&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;set&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; ~/my-project-dir/.env&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; +a
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'set -a; source ~/my-project-dir/.env; set +a'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.virtualenvs/my-project-virtualenv/bin/postactivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test this out by activating your virtualenv, with, e.g., workon my-project-virtualenv and then trying to run, e.g., echo $SECRET_KEY.&lt;/p&gt;

&lt;p&gt;You should see your SECRET_KEY printed to console if you see that everything is set up properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; If you change or add new environment variables, you have to reload the .env file in the console, as we did above. Otherwise, your Django project won’t have access to them.&lt;/p&gt;

&lt;p&gt;That takes care of our environment variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring MySQL Database
&lt;/h2&gt;

&lt;p&gt;Lastly, let’s configure our Django application to use MySQL. Head over to the Database tab in pythonanywhere and initialize MySQL.&lt;/p&gt;

&lt;p&gt;Once the database is initialized, we need to edit our settings.py file to configure the MySQL database. Navigate to your settings.py file and open the in-browser editor.&lt;/p&gt;

&lt;p&gt;Scroll down to the Database settings and replace it with 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="s"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'ENGINE'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'django.db.backends.mysql'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'NAME'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;your_username&amp;gt;$&amp;lt;your_database_name&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'USER'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;your_username&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;your_mysql_password&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'HOST'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;your_username&amp;gt;.mysql.pythonanywhere-services.com'&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;Navigate back to the database tab to get the configuration settings. All the settings are under the Connection and Your Databases sections. Save your settings.py file when you’re done.&lt;/p&gt;

&lt;p&gt;Next, we need to install the python-mysql connector so we can connect to the database. Open your bash console and activate your project virtual environment, then run the following command:&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;mysqlclient
python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When that is finished installing, navigate back over to your web tab and reload your website. To see your web application, click on the link at the top of the web tab or enter your pythonanywhere domain name in your browser.&lt;/p&gt;

&lt;p&gt;Don’t forget to go back and set environment variables for your database password as we did for the secret key.&lt;/p&gt;

&lt;p&gt;All done! Congratulations on making it this far. It was a long tutorial, but it was worth it. Now you have a Django application up and running.&lt;/p&gt;

&lt;p&gt;For more articles, check out my blog &lt;a href="https://engineertodeveloper.com/"&gt;EngineerToDeveloper&lt;/a&gt;.&lt;/p&gt;

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