<?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>Forem: Jonathan Farinloye</title>
    <description>The latest articles on Forem by Jonathan Farinloye (@jonathanfarinloye).</description>
    <link>https://forem.com/jonathanfarinloye</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%2F181212%2F3175cb3d-e697-41e6-9452-f2a730a18fe8.jpeg</url>
      <title>Forem: Jonathan Farinloye</title>
      <link>https://forem.com/jonathanfarinloye</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jonathanfarinloye"/>
    <language>en</language>
    <item>
      <title>Models, Views, Templates - Lesson 5</title>
      <dc:creator>Jonathan Farinloye</dc:creator>
      <pubDate>Tue, 25 Jun 2019 09:09:27 +0000</pubDate>
      <link>https://forem.com/jonathanfarinloye/models-views-templates-lesson-5-266n</link>
      <guid>https://forem.com/jonathanfarinloye/models-views-templates-lesson-5-266n</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Templates to Views to Models&lt;/li&gt;
&lt;li&gt;Displaying From Models&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;In the last article, we discussed how we can create a blog model in our blog app. This model contained a title, a cover image, a date field, a content field, and a slug field. Out of all these fields, we would be working on and interacting with the title, cover image and content fields. We would also be setting the date field to be automatically set to the date of the last update to our blog post, and the slug to be automatically set based on the title. I think that's a nice place to start. 🤔&lt;/p&gt;

&lt;p&gt;Move over to your &lt;strong&gt;&lt;em&gt;blog/models.py&lt;/em&gt;&lt;/strong&gt; file and edit the field called &lt;strong&gt;&lt;em&gt;raw_date&lt;/em&gt;&lt;/strong&gt;. Also add the &lt;strong&gt;&lt;em&gt;save&lt;/em&gt;&lt;/strong&gt; function to the class.&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;# blog/models py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.template.defaultfilters&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;slugify&lt;/span&gt; &lt;span class="c1"&gt;# a django module to take care of creating slugs
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;raw_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now&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="bp"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;slugify&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;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The parameter &lt;strong&gt;auto_now&lt;/strong&gt;, when set to &lt;strong&gt;True&lt;/strong&gt;, automatically sets the date to the latest date every time the model is edited and saved.&lt;br&gt;
Note also, the function we added must be named &lt;strong&gt;save&lt;/strong&gt; for this to work, because it, for lack of the right word, extends the original inbuilt save function. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do not forget to &lt;strong&gt;&lt;em&gt;makemigrations&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;migrate&lt;/em&gt;&lt;/strong&gt; your changes. Feel free to also test it to make sure it works. If you check the admin site, you would not find the date field anymore. This is because it is being automatically set. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fftc9swldsdshi52f979f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fftc9swldsdshi52f979f.jpg" alt="Date field seems to have disappeared"&gt;&lt;/a&gt;Date was eaten by a hungry squirrel 🐿️&lt;/p&gt;

&lt;h2&gt;
  
  
  Templates to Views to Models&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Don't get confused by the long heading. It's not that serious really 😉. Or is it 🤔? Just kidding. On a more serious note though, our main goal is to allow blog posts to be created from the frontend and to do this, we basically need just a form that has the fields of the model we created, with an exception of the automatically populated fields (I was going to say filled fields). So we need to create an HTML file that would hold the form (We really aren't bothering about the styling now. Feel free, though, to style however you want). &lt;/p&gt;

&lt;p&gt;Move over to your &lt;strong&gt;&lt;em&gt;blog&lt;/em&gt;&lt;/strong&gt; app and create a &lt;strong&gt;&lt;em&gt;templates&lt;/em&gt;&lt;/strong&gt; directory if you don't already have one. Next, create a file, I'd name mine &lt;strong&gt;&lt;em&gt;add-blog&lt;/em&gt;&lt;/strong&gt;. So, &lt;strong&gt;&lt;em&gt;blog/templates/add-blog.html&lt;/em&gt;&lt;/strong&gt;. Let's move over to our &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt; and create the function for our add a blog page.&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="bp"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;# blog/views.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_blog_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;add-blog.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For now, we'd just return the html document&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We need to create a &lt;strong&gt;&lt;em&gt;urls.py&lt;/em&gt;&lt;/strong&gt; file inside the blog app and link the file to the main &lt;strong&gt;&lt;em&gt;urls.py&lt;/em&gt;&lt;/strong&gt; inside the &lt;strong&gt;&lt;em&gt;awesome&lt;/em&gt;&lt;/strong&gt; directory.&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;# blog/urls.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;add-post/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_blog_post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;add-a-post&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;In &lt;strong&gt;&lt;em&gt;awesome/urls.py&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# awesome/urls.py
&lt;/span&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;counts/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;count-vowels&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;# Don't forget this comma
&lt;/span&gt;    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;blog/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;blog.urls&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The new line includes the blog/urls.py file in the recognized urls.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, go back to your html file and create the form.&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="c"&gt;&amp;lt;!-- blog/templates/add-blog.html --&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"{% url 'add-a-post' %}"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;enctype=&lt;/span&gt;&lt;span class="s"&gt;"multipart/form-data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    {% csrf_token %}
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"title-field"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Title&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"title-field"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"cover"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cover Image&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cover"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"cover-image"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"blog-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Content&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"blog-content"&lt;/span&gt; &lt;span class="na"&gt;rows=&lt;/span&gt;&lt;span class="s"&gt;"20"&lt;/span&gt; &lt;span class="na"&gt;cols=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Don't forget to include your csrf_token, else it won't work &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7r8sn8c3i2oh1hsi81wy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7r8sn8c3i2oh1hsi81wy.jpg" alt="Image showing how form looks"&gt;&lt;/a&gt;Please style if you can. This thing is ugly.&lt;/p&gt;

&lt;p&gt;Now, go to &lt;strong&gt;&lt;em&gt;blog/views.py&lt;/em&gt;&lt;/strong&gt; and let's make changes to the function.&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;# blog/views,py
&lt;/span&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blog&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_blog_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cover&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FILES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cover-image&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;home&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;add-blog.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: This fetches the information from the name given to each of the fields, meaning if you don't give it a name, accessing the information might be difficult.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When we run &lt;strong&gt;blog.save()&lt;/strong&gt;, a blog post is created with the given information. Save your code, and test it. Login to the admin site and confirm that it saves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpcqyjsbrkxw3pgrrktg8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpcqyjsbrkxw3pgrrktg8.jpg" alt="Image showing newly created blog post"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1hnx0v358k0vhye8n2ob.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1hnx0v358k0vhye8n2ob.jpg" alt="Image showing newly created blog post on the admin site"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Displaying from Models&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Currently when a blog post is created, we redirect the user to the home page. Not so ideal. We would want to redirect the user, however, to a page that lists all out posts. To do this, we need a page, a function and a new url entry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;blog/views.py&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# blog/views.py
&lt;/span&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;all_posts&lt;/span&gt;&lt;span class="p"&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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requests&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;all-posts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;blog/templates/all-posts.html&lt;/em&gt;&lt;/strong&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="c"&gt;&amp;lt;!-- blog/templates/all-posts.html --&amp;gt;&lt;/span&gt;
...
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
{% for post in all %}
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;{{ post.title }}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    {{ post.date }}
    &lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
    {{ post.content }}
    &lt;span class="nt"&gt;&amp;lt;hr&amp;gt;&lt;/span&gt;
{% endfor %}
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;blog/urls.py&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# blog/urls.py
&lt;/span&gt;&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;add-post/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_blog_post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;add-a-post&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;all-posts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all_posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;all-posts&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="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This are all the changes made and their respective files. And just like this, we are able to access and display our blog posts on the frontend. &lt;/p&gt;

&lt;p&gt;I'd want you to, in your own free time, extend the blog model. Try adding categories using the ManytoMany field. We'd be extending the model and possibly dealing with user accounts soon. &lt;/p&gt;

&lt;p&gt;One thing to note is, there are other ways to handle forms in Django. This is one, and not the only way. Feel free to check around for other methods and possibly try them too. 🦉. Stay safe. Be nice. Enjoy your day. &lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Models - Lesson 4</title>
      <dc:creator>Jonathan Farinloye</dc:creator>
      <pubDate>Fri, 21 Jun 2019 08:38:50 +0000</pubDate>
      <link>https://forem.com/jonathanfarinloye/models-lesson-4-313d</link>
      <guid>https://forem.com/jonathanfarinloye/models-lesson-4-313d</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Models&lt;/li&gt;
&lt;li&gt;Creating Models&lt;/li&gt;
&lt;li&gt;Registering Models&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;We can describe models as representations of real-world data or objects. For example a blog post. If we are to build a model around a blog post, we could have a &lt;strong&gt;&lt;em&gt;title&lt;/em&gt;&lt;/strong&gt;, the &lt;strong&gt;&lt;em&gt;date of publishing&lt;/em&gt;&lt;/strong&gt;, maybe a &lt;strong&gt;&lt;em&gt;cover image&lt;/em&gt;&lt;/strong&gt;, definitely the &lt;strong&gt;&lt;em&gt;body&lt;/em&gt;&lt;/strong&gt; of the post. Let us work with this and see how we can model these bits of information.&lt;/p&gt;

&lt;p&gt;As you might have thought, since we are talking about the blog, we would be working inside the blog app now. And since we are dealing with creating models, we would be working with the &lt;strong&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/strong&gt; file. &lt;/p&gt;

&lt;p&gt;However, before creating the model, let us edit our &lt;strong&gt;&lt;em&gt;settings.py&lt;/em&gt;&lt;/strong&gt; file to prepare our Django project to accept media files, in this case, the cover image. Move over to &lt;strong&gt;&lt;em&gt;settings.py&lt;/em&gt;&lt;/strong&gt; file, and at the bottom add:&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="mf"&gt;123.&lt;/span&gt; &lt;span class="n"&gt;MEDIA_ROOT&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;media/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;124.&lt;/span&gt;
&lt;span class="mf"&gt;125.&lt;/span&gt; &lt;span class="n"&gt;MEDIA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/media/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MEDIA_ROOT is set to a folder named 'media' inside the base directory of the project. While the MEDIA_URL is what URL would be used to access media files.&lt;/p&gt;

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

&lt;p&gt;Models are similar to objects. Well, they are actually objects and creating them looks 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="mf"&gt;1.&lt;/span&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="bp"&gt;...&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can read more about Django models &lt;a href="https://docs.djangoproject.com/en/2.2/topics/db/models/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
You can also give it another name asides &lt;strong&gt;&lt;em&gt;Blog&lt;/em&gt;&lt;/strong&gt;, but since we are dealing with the blog app, this name is reasonable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our model we need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A field for post Title&lt;/li&gt;
&lt;li&gt;A field for Date&lt;/li&gt;
&lt;li&gt;A field for Cover image&lt;/li&gt;
&lt;li&gt;A field for post Content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://docs.djangoproject.com/en/2.2/ref/models/fields/#model-field-types" rel="noopener noreferrer"&gt;Django site&lt;/a&gt; gives us quite a lot of fields that we can use in our objects. Searching through the site, we find some we might need.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CharField for the title&lt;/li&gt;
&lt;li&gt;DateTimeField for the dateeverytime&lt;/li&gt;
&lt;li&gt;ImageField for the cover image&lt;/li&gt;
&lt;li&gt;TextField for the post &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let us create our model and see how it looks:&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="mf"&gt;4.&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="mf"&gt;5.&lt;/span&gt;     &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt;     &lt;span class="n"&gt;raw_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="mf"&gt;7.&lt;/span&gt;     &lt;span class="n"&gt;cover&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;ImageField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;8.&lt;/span&gt;     &lt;span class="n"&gt;content&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;TextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The title is set to models.CharField, and the max_length attribute is set to 50 characters. The max_length attribute is a required argument for the CharField.&lt;br&gt;
The DateTimeField and the DateField fields require no positional argument. However, it could take some optional argument, such as &lt;strong&gt;&lt;em&gt;auto_now&lt;/em&gt;&lt;/strong&gt; which sets it to the current date and time every time the model is updated. You can find others &lt;a href="https://docs.djangoproject.com/en/2.2/ref/models/fields/#datefield" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Also to format the date in a more presentable format we could use &lt;a href="https://docs.python.org/3/library/time.html#time.strftime" rel="noopener noreferrer"&gt;strftime&lt;/a&gt;. To do that we would be adding a function to our object.&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="mf"&gt;10.&lt;/span&gt;     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;date&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="mf"&gt;11.&lt;/span&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upload_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%b %d, %Y&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As explained on the &lt;a href="https://docs.python.org/3/library/time.html#time.strftime" rel="noopener noreferrer"&gt;site&lt;/a&gt;, this formating method &lt;strong&gt;&lt;em&gt;%b %d, %Y&lt;/em&gt;&lt;/strong&gt;,would give a result like Jun 12, 2019 or Nov 13, 2019. &lt;/p&gt;

&lt;p&gt;The next field is the TextField which is used for the content. We use a TextField and not a CharField because TextField is designed for long text content. If yoy remember, we said CharField requires a &lt;strong&gt;&lt;em&gt;max_length&lt;/em&gt;&lt;/strong&gt; attribute. This attribute isn't required by a &lt;strong&gt;&lt;em&gt;TextField&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your &lt;strong&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/strong&gt;, at this point, should look like:&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="mf"&gt;1.&lt;/span&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="mf"&gt;2.&lt;/span&gt;  
&lt;span class="mf"&gt;3.&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt;  &lt;span class="c1"&gt;# Create your models here.
&lt;/span&gt;&lt;span class="mf"&gt;5.&lt;/span&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt;      &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;7.&lt;/span&gt;      &lt;span class="n"&gt;raw_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="mf"&gt;8.&lt;/span&gt;      &lt;span class="n"&gt;cover&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;ImageField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;9.&lt;/span&gt;      &lt;span class="n"&gt;content&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;TextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="mf"&gt;10.&lt;/span&gt;      
&lt;span class="mf"&gt;11.&lt;/span&gt;      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;date&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="mf"&gt;12.&lt;/span&gt;          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%b %d %Y&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Registering Models&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fapnh5gwy9r3dr5l01jsk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fapnh5gwy9r3dr5l01jsk.png" alt="Current admin site containing only default content"&gt;&lt;/a&gt;This is what our admin site looks like now&lt;br&gt;
To register a model we have created is to make it 'show up' in the admin site so we can add content and edit content. To register a model we open the &lt;strong&gt;&lt;em&gt;admin.py&lt;/em&gt;&lt;/strong&gt; file inside our blog app and add a few lines.&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="mf"&gt;1.&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blog&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt; &lt;span class="c1"&gt;# Register your models here.
&lt;/span&gt;&lt;span class="mf"&gt;4.&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This registers the model named Blog, on the admin site.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpfvsgmn9h88y4tqe4ouz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpfvsgmn9h88y4tqe4ouz.png" alt="New admin site showing Blog model"&gt;&lt;/a&gt;Refreshing the admin site shows the Blog Model&lt;/p&gt;

&lt;p&gt;However, if you try clicking on the Blog section, you get an Operational error. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F89neqxzxr48jogz81vig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F89neqxzxr48jogz81vig.png" alt="Operational Error on trying to load Blog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The exception value is 'no such table blog_blog'. This might tell you that it's a database problem. Remembering something we learned in an earlier section about &lt;a href="https://dev.to/jonathanfarinloye/moving-forward-lesson-2-1ibe#database"&gt;databases&lt;/a&gt;, we need to migrate the changes we have made to the &lt;strong&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/strong&gt; file. Almost all changes to &lt;strong&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/strong&gt; would require migrations before moving on. To do this, open your terminal, makemigrations and then migrate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/awesome-project$ python manage.py makemigrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: A migrations folder is automatically created inside the blog directory. Never delete this folder as it could cause serious issues for your app and database. Speaking from experience 😵. It's fixable though, just in case you're curious. 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Loading the admin site and checking the Blog opens a page that shows we have 0 Blog posts. Click on the add button to add a post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5z8aqcqmhpboyw6zfy5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F5z8aqcqmhpboyw6zfy5x.png" alt="Add post page"&gt;&lt;/a&gt;Shows all the fields we created. 🍉 for you&lt;/p&gt;

&lt;p&gt;Saving the new post, we see it named a "Blog object (1)". We don't want this. To adjust this we another function:&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="mf"&gt;14.&lt;/span&gt;     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="mf"&gt;15.&lt;/span&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This change doesn't require migrations. If you attempt to migrate, it says 'No changes detected'.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you check the blog app in the admin site now, you would see that 'Blog object (1)' has changed to the title of the blog post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvvlyqkj7jf6vzl52ii5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvvlyqkj7jf6vzl52ii5o.png" alt="Blog app on the admin site"&gt;&lt;/a&gt;What the Blog app looks like&lt;/p&gt;

&lt;p&gt;We can leave this page as it is, but to make it easier we could do a bit of customization. Open your &lt;strong&gt;&lt;em&gt;admin.py&lt;/em&gt;&lt;/strong&gt; file and edit it to look similar 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="mf"&gt;1.&lt;/span&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blog&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;  &lt;span class="c1"&gt;# Register your models here.
&lt;/span&gt;&lt;span class="mf"&gt;4.&lt;/span&gt;
&lt;span class="mf"&gt;5.&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="mf"&gt;7.&lt;/span&gt;      &lt;span class="n"&gt;list_display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;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;date&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;cover&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;8.&lt;/span&gt;      &lt;span class="n"&gt;search_fields&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;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;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mf"&gt;9.&lt;/span&gt;    
&lt;span class="mf"&gt;10.&lt;/span&gt;
&lt;span class="mf"&gt;11.&lt;/span&gt;  &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlogAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refreshing the blog app, we see a new look.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvys5uv7ukokov4sep73n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvys5uv7ukokov4sep73n.png" alt="Blog app now includes date, link to image, as well as a search bar"&gt;&lt;/a&gt;Now includes date, link to image, as well as a search bar&lt;/p&gt;

&lt;p&gt;One last thing we would do is add a slug field. To do this, we first add a new field to our model:&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="mf"&gt;5.&lt;/span&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt;      &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;7.&lt;/span&gt;      &lt;span class="n"&gt;raw_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="mf"&gt;8.&lt;/span&gt;      &lt;span class="n"&gt;cover&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;ImageField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;9.&lt;/span&gt;      &lt;span class="n"&gt;content&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;TextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;      &lt;span class="n"&gt;slug&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;SlugField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could set a max_length attribute for the SlugField or not. If you don't set it, Django used 50 by default. The next thing we would do is set the slug as a &lt;strong&gt;&lt;em&gt;prepopulated field&lt;/em&gt;&lt;/strong&gt;. This would automatically set the slug based on one or more other fields. We want our slug to depend on the title so in &lt;strong&gt;&lt;em&gt;admin.py&lt;/em&gt;&lt;/strong&gt; we add a new line to the class:&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="mf"&gt;1.&lt;/span&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blog&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;  &lt;span class="c1"&gt;# Register your models here.
&lt;/span&gt;&lt;span class="mf"&gt;4.&lt;/span&gt;
&lt;span class="mf"&gt;5.&lt;/span&gt;
&lt;span class="mf"&gt;6.&lt;/span&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogAdmin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelAdmin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="mf"&gt;7.&lt;/span&gt;      &lt;span class="n"&gt;list_display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;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;date&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;cover&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;slug&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;8.&lt;/span&gt;      &lt;span class="n"&gt;search_fields&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;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;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mf"&gt;9.&lt;/span&gt;      &lt;span class="n"&gt;prepopulated_fields&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;slug&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;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,)}&lt;/span&gt;
&lt;span class="mf"&gt;10.&lt;/span&gt;
&lt;span class="mf"&gt;11.&lt;/span&gt;
&lt;span class="mf"&gt;12.&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BlogAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Line 8 set the slug as a 'prepopulated' field that depends on the title. We also added &lt;strong&gt;&lt;em&gt;slug&lt;/em&gt;&lt;/strong&gt; to the list display to see what our slug is. If you attempt to makemigrations now (due to adding a new field), Django would give you 2 options, either provide a one-off default for already existing rows or quit and set a default in models.py. This is why it is better to completely build our model before adding objects to the database. &lt;br&gt;
To move forward from this issue, we can quit and set a default in the &lt;strong&gt;&lt;em&gt;models.py&lt;/em&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="mf"&gt;10.&lt;/span&gt;     &lt;span class="n"&gt;slug&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;SlugField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;random-text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the migrations again, migrate, then go to the already existing blog post, tweak the name a bit(you could add a space and remove it 😉)Just to trick the system to automatically set the name. Once done, save and check that everything works. When you're done, you can remove the default attribute in the SlugField, makemigrations and migrate again (It won't make much sense if multiple blog posts have the same slug🤷🏾‍♂️🤷🏾‍♀️).&lt;/p&gt;

&lt;p&gt;You can read more about customizing the Django ModelAdmin &lt;a href="https://docs.djangoproject.com/en/2.2/ref/contrib/admin/#module-django.contrib.admin" rel="noopener noreferrer"&gt;here&lt;/a&gt;. In the next article, we would be seeing how we can add blog posts from the site, without going into the admin site.&lt;br&gt;
&lt;small&gt;Project can be found &lt;a href="https://github.com/JonathanFarinloye/Beginners_Tutorial_Django" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/small&gt;&lt;br&gt;
&lt;small&gt;There would be no articles over the weekend. Play around with what you've learned and use it to create something nice. Enjoy your weekend&lt;/small&gt;&lt;br&gt;
Until then, 🍊🍎🍍 &lt;/p&gt;

&lt;h3&gt;
  
  
  Cheers ✨✨
&lt;/h3&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Views - Lesson 3</title>
      <dc:creator>Jonathan Farinloye</dc:creator>
      <pubDate>Wed, 19 Jun 2019 21:22:44 +0000</pubDate>
      <link>https://forem.com/jonathanfarinloye/views-lesson-3-3gc6</link>
      <guid>https://forem.com/jonathanfarinloye/views-lesson-3-3gc6</guid>
      <description>&lt;p&gt;In this lesson, we would be discussing further uses of the views.py file other than just returning an HTML page. To do this we would be building a small app while we make a few changes to the way our current homepage is displayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changes to Make
&lt;/h2&gt;

&lt;p&gt;Currently, our Homepage is served from the &lt;strong&gt;&lt;em&gt;blog&lt;/em&gt;&lt;/strong&gt; app, but we should honestly leave the &lt;strong&gt;&lt;em&gt;blog&lt;/em&gt;&lt;/strong&gt; for only blog related things. Meaning we have to move our homepage out, probably to the root directory. The first thing we would do is create a folder called &lt;strong&gt;&lt;em&gt;templates&lt;/em&gt;&lt;/strong&gt; in the &lt;strong&gt;&lt;em&gt;awesome-project&lt;/em&gt;&lt;/strong&gt; directory. Second, move the &lt;strong&gt;&lt;em&gt;home.html&lt;/em&gt;&lt;/strong&gt; file to this newly created folder.&lt;/p&gt;

&lt;p&gt;Next, go to &lt;strong&gt;&lt;em&gt;settings.py&lt;/em&gt;&lt;/strong&gt;. Around line &lt;strong&gt;&lt;em&gt;55&lt;/em&gt;&lt;/strong&gt;, we see &lt;strong&gt;&lt;em&gt;TEMPLATES&lt;/em&gt;&lt;/strong&gt;. Inside the list of &lt;strong&gt;&lt;em&gt;DIRS&lt;/em&gt;&lt;/strong&gt; add &lt;strong&gt;&lt;em&gt;'templates'&lt;/em&gt;&lt;/strong&gt;, which is the name of the templates folder we created.&lt;br&gt;
So, my line 58 looks like:&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="mf"&gt;58.&lt;/span&gt;        &lt;span class="s"&gt;'DIRS'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'templates'&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 create a &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt; file inside the &lt;strong&gt;&lt;em&gt;awesome&lt;/em&gt;&lt;/strong&gt; directory. and copy the content from the &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt; inside the &lt;strong&gt;&lt;em&gt;blog&lt;/em&gt;&lt;/strong&gt; directory. You can go ahead and delete the function we created in the previous &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt;. And make appropriate changes to the &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt; inside the &lt;strong&gt;&lt;em&gt;awesome&lt;/em&gt;&lt;/strong&gt; directory.&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="mf"&gt;1.&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;
    &lt;span class="mf"&gt;2.&lt;/span&gt;
    &lt;span class="mf"&gt;3.&lt;/span&gt; &lt;span class="c1"&gt;# Create your views here.
&lt;/span&gt;    &lt;span class="mf"&gt;4.&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;home&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="mf"&gt;5.&lt;/span&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'home.html'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This should be inside &lt;strong&gt;&lt;em&gt;awesome/views.py&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One more change we should make, assuming I'm not missing anything out, is to the &lt;strong&gt;&lt;em&gt;awesome/urls.py&lt;/em&gt;&lt;/strong&gt; file. Instead of having:&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="mf"&gt;18.&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;blog&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have:&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="mf"&gt;18.&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This means - from this directory, import views.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Save all files, run your server and make sure your home page still displays. If it does, let's move on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1sQaJYkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/72hrh1si56fayr17t83m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1sQaJYkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/72hrh1si56fayr17t83m.png" alt="Testing changes made to the site; new home page"&gt;&lt;/a&gt;It's not yet time for a carrot 😏.&lt;/p&gt;

&lt;h2&gt;
  
  
  Views.py
&lt;/h2&gt;

&lt;p&gt;So to dive into this, we'd be adding a form to our home page that counts the number of vowels in some text. It's a good practice to highlight what would be needed. Thinking of this problem and what we have learnt so far, we would be needing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A form that we use to collect user input;&lt;/li&gt;
&lt;li&gt;A function that counts the vowels;&lt;/li&gt;
&lt;li&gt;A page that we return the number of vowels to.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So let us start with no. 1. Adding a form. For the sake of simplicity, we would be adding it to the homepage.&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;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input-stuff"&lt;/span&gt; &lt;span class="na"&gt;rows=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;cols=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Check vowel count&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, here's what my form looks like. Notice I have a method and action on the form tag and a name on my textarea tag. The method is &lt;strong&gt;&lt;em&gt;POST&lt;/em&gt;&lt;/strong&gt; because it's a &lt;strong&gt;&lt;em&gt;POST&lt;/em&gt;&lt;/strong&gt; request. The action is the &lt;strong&gt;&lt;em&gt;url&lt;/em&gt;&lt;/strong&gt; that should be triggered when the button is clicked. We would get back to it. Let's go create our function. &lt;br&gt;
No. 2&lt;br&gt;
We'd be naming our function counter. and it would look 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;# awesome/views.py
&lt;/span&gt;    &lt;span class="mf"&gt;8.&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;counter&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="mf"&gt;9.&lt;/span&gt;     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="mf"&gt;10.&lt;/span&gt;         &lt;span class="n"&gt;vow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="mf"&gt;11.&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'input-stuff'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="mf"&gt;12.&lt;/span&gt;             &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'aeiou'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="mf"&gt;13.&lt;/span&gt;                 &lt;span class="n"&gt;vow&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of this code might look familiar, except line 9 and line 11. Line 9 checks if the request method is a &lt;strong&gt;&lt;em&gt;POST&lt;/em&gt;&lt;/strong&gt;. A &lt;strong&gt;&lt;em&gt;POST&lt;/em&gt;&lt;/strong&gt; request is basically used when sending certain information to the server. Usually from a form. Line 11, on the other hand, is used to access the information inputted in the textarea. Remember that we named the textarea &lt;strong&gt;&lt;em&gt;input-stuff&lt;/em&gt;&lt;/strong&gt;. Well, this helps to access it. One thing we must not forget is that our function must &lt;strong&gt;always&lt;/strong&gt; return something. If it doesn't we would most likely get error 500. So the question is: what do we return? Simple. A page to display the result.&lt;br&gt;
No. 3&lt;br&gt;
Let's create an HTML file called &lt;strong&gt;&lt;em&gt;count&lt;/em&gt;&lt;/strong&gt; in the &lt;strong&gt;&lt;em&gt;templates&lt;/em&gt;&lt;/strong&gt; directory. We would be back to what should be inside it in a few. Okay... That's a lot of things on hold. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Action in the form tag.&lt;/li&gt;
&lt;li&gt;A return statement in the counter function.&lt;/li&gt;
&lt;li&gt;The content of the count.html file&lt;/li&gt;
&lt;li&gt;The url that would lead to the counter function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let us handle the &lt;strong&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/strong&gt; first. We need a return statement. Our return statement would return the page and a bit of extra information: the number of counted vowels. How do we do this? Well:&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="mf"&gt;8.&lt;/span&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;counter&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="mf"&gt;9.&lt;/span&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="mf"&gt;10.&lt;/span&gt;         &lt;span class="n"&gt;vow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="mf"&gt;11.&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'input-stuff'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="mf"&gt;12.&lt;/span&gt;             &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'aeiou'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="mf"&gt;13.&lt;/span&gt;                 &lt;span class="n"&gt;vow&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="mf"&gt;14.&lt;/span&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'count.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'count'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vow&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay. Wait a minute. We recognize that last part &lt;strong&gt;&lt;em&gt;{'count': vow}&lt;/em&gt;&lt;/strong&gt; as a python dictionary. So we could use this to pass extra information back to the page that we are also returning; in this case, the &lt;strong&gt;&lt;em&gt;count.html&lt;/em&gt;&lt;/strong&gt; page. &lt;br&gt;
One thing we should also address if someone tries to visit the &lt;strong&gt;&lt;em&gt;count.html&lt;/em&gt;&lt;/strong&gt; page without going through the home page. Let's just set it to send them to the homepage. For this, we would need to import redirect.&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="mf"&gt;1.&lt;/span&gt;  &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="mf"&gt;8.&lt;/span&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;counter&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="mf"&gt;9.&lt;/span&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="mf"&gt;10.&lt;/span&gt;         &lt;span class="n"&gt;vow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="mf"&gt;11.&lt;/span&gt;         &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'input-stuff'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="mf"&gt;12.&lt;/span&gt;             &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s"&gt;'aeiou'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="mf"&gt;13.&lt;/span&gt;                 &lt;span class="n"&gt;vow&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="mf"&gt;14.&lt;/span&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'count.html'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'count'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vow&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="mf"&gt;15.&lt;/span&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'home'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Line 15 gives us what we are looking for. Meaning, if the request isn't a &lt;strong&gt;&lt;em&gt;POST&lt;/em&gt;&lt;/strong&gt; request, it would not encounter the first return statement and would move to the next. The return statement on line 15 says: redirect the user to a url with the name of &lt;strong&gt;&lt;em&gt;home&lt;/em&gt;&lt;/strong&gt;. We use the url name, not the html file. Note.&lt;/p&gt;

&lt;p&gt;Now, let us move to creating the url. Move over to your &lt;strong&gt;&lt;em&gt;awesome/urls.py&lt;/em&gt;&lt;/strong&gt; file, let's add another path.&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="mf"&gt;20.&lt;/span&gt; &lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="mf"&gt;21.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'some-random-text/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;22.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'home'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;23.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'count/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;24.&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;New path is on line 23. If the comma at the end of line 23 is missing, we would face issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This shouldn't be strange. Remember to add a comma to end of every closing bracket. You might also notice that I didn't add a name to the &lt;strong&gt;&lt;em&gt;count&lt;/em&gt;&lt;/strong&gt; url and we would get to that shortly. &lt;br&gt;
Now let's go to the &lt;strong&gt;&lt;em&gt;home.html&lt;/em&gt;&lt;/strong&gt; file and make one minor addition. We would add the action, which would be the url, which is &lt;strong&gt;&lt;em&gt;/count/&lt;/em&gt;&lt;/strong&gt;. And then we head over to &lt;strong&gt;&lt;em&gt;count.html&lt;/em&gt;&lt;/strong&gt; and add some strange stuff to the body:&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;h3&amp;gt;&lt;/span&gt; Vowels Counted - {{ count }}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This definitely isn't regular html. However, Django allows us to access the contents of the dictionary we returned using this syntax.i.e.&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="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;dictionary_key_name&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run your server and check if your code runs.&lt;br&gt;
Mine doesn't 😫😩. However, because DEBUG = True in &lt;strong&gt;&lt;em&gt;settings.py&lt;/em&gt;&lt;/strong&gt;, we see the error has to do with &lt;strong&gt;&lt;em&gt;CRSF verification failed&lt;/em&gt;&lt;/strong&gt;. Well Django requires that for every form, there is a&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="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;csrf_token&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;CSRF stands for Cross Site Reference Forgery. You should read a little about it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To prevent againt CSRF, a token is generated on every form submission. So let's go add it:&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;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {% csrf_token %}
        &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"input-stuff"&lt;/span&gt; &lt;span class="na"&gt;rows=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;cols=&lt;/span&gt;&lt;span class="s"&gt;"30"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Check vowel count&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now save, and try again. Ding! Ding!! Ding!!🛎🛎🛎😁😄&lt;br&gt;
Mine works! If yours does, 🍓🍓 strawberries for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gNmvPFWv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i07kj0rkndx11syelol4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gNmvPFWv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/i07kj0rkndx11syelol4.png" alt="Vowel counter works!"&gt;&lt;/a&gt;&lt;/p&gt;
Awesome work, . You're the best



&lt;p&gt;One final thing is to test what happens when we change the url from &lt;strong&gt;&lt;em&gt;count&lt;/em&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;em&gt;counts&lt;/em&gt;&lt;/strong&gt; in the &lt;strong&gt;&lt;em&gt;urls.py&lt;/em&gt;&lt;/strong&gt; 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="mf"&gt;20.&lt;/span&gt; &lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="mf"&gt;21.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'some-random-text/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;22.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'home'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;23.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'counts/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;24.&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DI1YkHyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2fjscyhxiv5umae5sbti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DI1YkHyZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2fjscyhxiv5umae5sbti.png" alt="404 Django"&gt;&lt;/a&gt;404 error just by changing count to counts&lt;br&gt;
Trying again, we get a 404 error, because the url changed. To combat this e could use the name of the url. So add a name to the &lt;strong&gt;&lt;em&gt;count&lt;/em&gt;&lt;/strong&gt; url.&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="mf"&gt;20.&lt;/span&gt; &lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="mf"&gt;21.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'some-random-text/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;22.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'home'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;23.&lt;/span&gt;     &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'count/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'count-vowels'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mf"&gt;24.&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now go to &lt;strong&gt;&lt;em&gt;home.html&lt;/em&gt;&lt;/strong&gt; and make your opening form tag similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;9. &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"{% url 'count-vowels' %}"&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;Only the action changed to what is known as a &lt;strong&gt;template tag&lt;/strong&gt;. This basically says: search all the urls we have and see if there's any with the name &lt;strong&gt;count-vowels&lt;/strong&gt;. If there is, that is the url we want. And so that works.&lt;/p&gt;

&lt;p&gt;As we have seen, the &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt; file controls a number of things. This isn't all we can use it for. We would also be talking about &lt;strong&gt;models&lt;/strong&gt; and how we can upload images, maybe a profile picture. &lt;br&gt;
This would be the end of today's article. I know we've been eating fruits, but here 🍩🍿🍫🍪, give yourself a tasty treat if you choose to. Cheers.&lt;/p&gt;

&lt;p&gt;I almost forgot the carrot, here 🥕🥕.&lt;br&gt;
&lt;small&gt;Project can be found &lt;a href="https://github.com/JonathanFarinloye/Beginners_Tutorial_Django"&gt;here&lt;/a&gt;&lt;/small&gt;&lt;br&gt;
&lt;small&gt;Cover image by &lt;a href="https://pixabay.com/users/yabayee-907690/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=705412"&gt;yabayee&lt;/a&gt; from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=705412"&gt;Pixabay&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Moving Forward - Lesson 2</title>
      <dc:creator>Jonathan Farinloye</dc:creator>
      <pubDate>Wed, 19 Jun 2019 07:04:23 +0000</pubDate>
      <link>https://forem.com/jonathanfarinloye/moving-forward-lesson-2-1ibe</link>
      <guid>https://forem.com/jonathanfarinloye/moving-forward-lesson-2-1ibe</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Get Familiar&lt;/li&gt;
&lt;li&gt;Database&lt;/li&gt;
&lt;li&gt;Apps&lt;/li&gt;
&lt;li&gt;Homepage&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Get Familiar&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I believe you either have a Python IDE or a code editor. I use Pycharm. Many people like VS Code. If you don't, go and download one before moving on.&lt;/p&gt;

&lt;p&gt;Hoping you have a Code Editor now, open your project in your editor. You might want to get familiar with the files and folders in your project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s-gCktdv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fyasui07xytrxvrj5gf7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s-gCktdv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fyasui07xytrxvrj5gf7.png" alt="files and folders in the project"&gt;&lt;/a&gt;Some really random files and stuff&lt;br&gt;
You might recognize the &lt;strong&gt;&lt;em&gt;'manage.py'&lt;/em&gt;&lt;/strong&gt; file, as it was the one we used when we wanted to run the server. You should have a file named &lt;strong&gt;&lt;em&gt;'db.sqlite3'&lt;/em&gt;&lt;/strong&gt;. This is the database file. It was automatically generated when we run the server. Other database services could be used - like Postgres, MySQL. However, we'd be working with the default. Later on, we could discuss setting up a Postgres Database.&lt;/p&gt;

&lt;p&gt;There is the &lt;strong&gt;&lt;em&gt;'__init__.py'&lt;/em&gt;&lt;/strong&gt; which just identifies the &lt;strong&gt;&lt;em&gt;'awesome'&lt;/em&gt;&lt;/strong&gt; directory as a group of python files, or what we can call a module. The &lt;strong&gt;&lt;em&gt;'settings.py'&lt;/em&gt;&lt;/strong&gt; file contains the settings for our Django project. We'd be diving into it as we move on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--93SuZWnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fgjcb0x1vm1wl8buk2ge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--93SuZWnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fgjcb0x1vm1wl8buk2ge.png" alt="Database settings in settings.py"&gt;&lt;/a&gt;A section of settings.py showing Database settings&lt;br&gt;
Then, we have &lt;strong&gt;&lt;em&gt;'urls.py'&lt;/em&gt;&lt;/strong&gt; which contains the URLs that our site would make use of. If you view it now, you see some comment and then one &lt;strong&gt;&lt;em&gt;'urlpattern'&lt;/em&gt;&lt;/strong&gt;, which is: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;urlpatterns = [
    path('admin/', admin.site.urls),
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you run your server now, make sure your virtual environment is active. Remember, to run the server:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;And then visit 127.0.0.1:8000/admin, you should see a sign in page that looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vliBBoeH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/y8vg39qcts24wllcpajc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vliBBoeH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/y8vg39qcts24wllcpajc.png" alt="Django admin page"&gt;&lt;/a&gt;Eat an apple for getting this far 🍏&lt;br&gt;
Lastly, we have the &lt;strong&gt;&lt;em&gt;'wsgi.py'&lt;/em&gt;&lt;/strong&gt; file. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Web Server Gateway Interface (WSGI) is a simple calling convention for web servers to forward requests to web applications or frameworks written in the Python programming language. &lt;a href="https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface"&gt;From Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In case you're curious, you would find extra information online. However, we won't be toying with this file much. I doubt we'd ever touch it.&lt;/p&gt;

&lt;p&gt;Before moving forward, we'd be renaming the folder up-top to &lt;strong&gt;&lt;em&gt;'awesome-project'&lt;/em&gt;&lt;/strong&gt; so as to differentiate it from the one that contains the &lt;strong&gt;&lt;em&gt;'urls.py'&lt;/em&gt;&lt;/strong&gt; and other files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wABotaDP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1mhviylwtqsnsff3manx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wABotaDP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1mhviylwtqsnsff3manx.png" alt="folder name changed"&gt;&lt;/a&gt;Renaming the wrong one would break everything😭&lt;/p&gt;

&lt;h2&gt;
  
  
  Database&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The database is, well the database. Stores information, data and a whole bunch of things. The first task we would be performing with the database is creating a &lt;strong&gt;&lt;em&gt;'superuser'&lt;/em&gt;&lt;/strong&gt;. A superuser has 'ultimate level access' to the entire project. Make sure you're careful with your superuser account. To create one, run:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;If you do this at this point, you would get a bunch of errors. Well, that's because the database hasn't been prepared to receive the information. Django has a nice way of managing the databases with its &lt;strong&gt;&lt;em&gt;migrations&lt;/em&gt;&lt;/strong&gt;. If a change that should be reflected in the database is performed, Django requests you to &lt;strong&gt;&lt;em&gt;'makemigrations'&lt;/em&gt;&lt;/strong&gt; and then &lt;strong&gt;&lt;em&gt;'migrate'&lt;/em&gt;&lt;/strong&gt;. Unapplied migrations always show up. Similar to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You have 17 unapplied migration(s). Your project may not work 
properly 
until you apply the migrations for app(s): admin, auth, contenttypes, 
sessions.
Run 'python manage.py migrate' to apply them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To makemigrations, run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/awesome-project$ python manage.py makemigrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If changes are detected, it prepares it for migration.&lt;/p&gt;

&lt;p&gt;To apply the migrations, run:&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;You get something like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This means you have successfully migrated your changes.&lt;br&gt;
Now, try creating your superuser again&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/awesome-project$ python manage.py createsuperuser
Username: we-awesome    
Email address: hello@awesome.us
Password: DjangoPass
Password (again): DjangoPass
Superuser created successfully.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I strongly advise you set a strong password. I'm only using this because it's for a tutorial. In real life projects. A strong password and a real email address are essential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now run your server again, visit the admin page via 127.0.0.1:8000/admin and login with your details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S662-48I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2k99awm4f17bi7cppr34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S662-48I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2k99awm4f17bi7cppr34.png" alt="Django's admin page"&gt;&lt;/a&gt;&lt;/p&gt;
Another apple for you, or maybe an orange🍊



&lt;p&gt;One thing you should know is, you can change the link to the admin page. so if you want to change it from &lt;strong&gt;&lt;em&gt;127.0.0.1:8000/admin&lt;/em&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;em&gt;127.0.0.1:8000/some-random-text&lt;/em&gt;&lt;/strong&gt;, just go the &lt;strong&gt;&lt;em&gt;urls.py&lt;/em&gt;&lt;/strong&gt; file and change it. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SdkGWCwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1d4f7drxkezy8670h8sd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SdkGWCwD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1d4f7drxkezy8670h8sd.png" alt="Changed url to admin page"&gt;&lt;/a&gt;&lt;/p&gt;
Previous and current line 20



&lt;blockquote&gt;
&lt;p&gt;Visiting &lt;strong&gt;&lt;em&gt;127.0.0.1:8000/some-random-text&lt;/em&gt;&lt;/strong&gt; opens the admin page; Visiting &lt;strong&gt;&lt;em&gt;127.0.0.1:8000/admin&lt;/em&gt;&lt;/strong&gt; gives a 404 error&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Apps&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;So what's the difference between a project and an app 🤔? Imagine a company with different teams. A &lt;strong&gt;&lt;em&gt;marketing&lt;/em&gt;&lt;/strong&gt; team, to well, market. A &lt;strong&gt;&lt;em&gt;design team&lt;/em&gt;&lt;/strong&gt;, you're on the &lt;strong&gt;&lt;em&gt;development&lt;/em&gt;&lt;/strong&gt; team. Your best friend is on the &lt;strong&gt;&lt;em&gt;administration&lt;/em&gt;&lt;/strong&gt; team and so on. Apps could be likened to the individual teams, while the project is like the company. We could create a &lt;strong&gt;&lt;em&gt;'blog'&lt;/em&gt;&lt;/strong&gt; app to manage blogging issues. We could have a &lt;strong&gt;&lt;em&gt;'profile'&lt;/em&gt;&lt;/strong&gt; app to manage user profiles and so on.&lt;/p&gt;

&lt;p&gt;Let us create a &lt;strong&gt;&lt;em&gt;'blog'&lt;/em&gt;&lt;/strong&gt; app.&lt;br&gt;
To create an app. Open your terminal in the &lt;strong&gt;&lt;em&gt;awesome-project&lt;/em&gt;&lt;/strong&gt; directory. Make sure your virtual environment is active, then run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/awesome-project$ django-admin startapp blog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;As usual, you can give it another name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm quite sure it worked✨✨! If not, 😟 review what you did and kindly tell me what went wrong. &lt;/p&gt;

&lt;p&gt;Creating the app also creates a bunch of files that we haven't seen before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X_2F-IGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ncmnvdk9vxhuzf39jlxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X_2F-IGK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ncmnvdk9vxhuzf39jlxl.png" alt="blog app directory and content"&gt;&lt;/a&gt;&lt;/p&gt;
That's a lot of strange stuff😕



&lt;p&gt;As we move forward and encounter them, we'd discuss what they are.&lt;/p&gt;

&lt;p&gt;We also need not forget to register the app in the &lt;strong&gt;&lt;em&gt;settings.py&lt;/em&gt;&lt;/strong&gt; file. (Actually, I forgot to register it as at the time of writing😬) To do this, open the &lt;strong&gt;&lt;em&gt;apps.py&lt;/em&gt;&lt;/strong&gt; file inside your &lt;strong&gt;&lt;em&gt;'blogs'&lt;/em&gt;&lt;/strong&gt; directory and copy the name of the class. In my case, it is &lt;strong&gt;&lt;em&gt;BlogConfig&lt;/em&gt;&lt;/strong&gt;. Now go to &lt;strong&gt;&lt;em&gt;settings.py&lt;/em&gt;&lt;/strong&gt;. Scroll till you see &lt;strong&gt;&lt;em&gt;INSTALLED_APPS&lt;/em&gt;&lt;/strong&gt;. A number of apps are there by default, however, we want to add a new one which is &lt;strong&gt;&lt;em&gt;BlogConfig&lt;/em&gt;&lt;/strong&gt;. Add a Comma after the last line before the ']', move to the next line, and add:&lt;br&gt;
    40. 'blog.apps.BlogConfig'&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;blog&lt;/em&gt;&lt;/strong&gt; - the name of the folder/app; &lt;strong&gt;&lt;em&gt;apps&lt;/em&gt;&lt;/strong&gt; - the name of the file; &lt;strong&gt;&lt;em&gt;BlogConfig&lt;/em&gt;&lt;/strong&gt; - the name of the class.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please don't forget as I did.😬😬&lt;/p&gt;

&lt;h2&gt;
  
  
  Homepage&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The last thing we would consider in this lesson is how to change the default homepage. By this, I mean the page that shows up on visiting 127.0.0.1:8000. To do this, we need to create a template, an HTML file.&lt;br&gt;
Let us use our blog app. Create a new folder inside the blog folder and name it &lt;strong&gt;&lt;em&gt;'templates'&lt;/em&gt;&lt;/strong&gt;. You could create your HTML file directly into this folder or further add subdirectories to organize the files. Either way is fine. (Edit: As an example, I created a main-site subdirectory in the templates directory. And that would reflect in my views.py.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2N21mWx_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6eujt5x3gnkfsacmn9bo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2N21mWx_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6eujt5x3gnkfsacmn9bo.png" alt="Folder structure and HTML file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can see both the folder arrangement and the placement of the HTML file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the question is: How do I get this file to display? This is where we visit the &lt;strong&gt;&lt;em&gt;view.py&lt;/em&gt;&lt;/strong&gt; file alongside &lt;strong&gt;&lt;em&gt;urls.py&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--poiPjGMc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wfj09is31bah6tsoo3z6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--poiPjGMc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/wfj09is31bah6tsoo3z6.jpg" alt="minamal way to show the flow of information from the user and back"&gt;&lt;/a&gt;This is a quite skeletal representation&lt;br&gt;
This isn't everything that happens, but this is all we need for now. So let's follow the image. The user's request takes a plane 🛬 and lands in the &lt;strong&gt;&lt;em&gt;'urls.py'&lt;/em&gt;&lt;/strong&gt; file. On getting there, it checks if the url exists. One thing you should know is our &lt;strong&gt;&lt;em&gt;'urls.py'&lt;/em&gt;&lt;/strong&gt; file deals with only the suffix. i.e It doesn't include the 127.0.0.1:8000 in itself. So keeping that in mind, if we want to replace the default home page, we add one line to &lt;strong&gt;&lt;em&gt;'urls.py'&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20. urlpatterns = [
21.     path('some-random-text/', admin.site.urls),
22.     path('',)
23. ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The newly added line says when they input the prefix(127.0.0.1:8000) without any suffix, come to me. The second box in our image says we should run the specified function in &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt;. Which means we have to create a function that returns something. And the question is what do we want to return? The HTML file. So let's go create our function. In &lt;strong&gt;&lt;em&gt;views.py&lt;/em&gt;&lt;/strong&gt;, create a function, name it. It takes in at least one argument, which we would name request. And then returns the render of the HTML document on the URL that was requested. I know it's sounding confusing. Get a pen and paper, draw the different sections and try linking them up. My function looks like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4. def home(request):
5.     return render(request, 'main-site/home.html')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The views automatically check the templates folder as the base directory of all HTML documents. Now to add the view to our url path, we first have to import it into the &lt;strong&gt;&lt;em&gt;urls.py&lt;/em&gt;&lt;/strong&gt; file. At the top of the file, add:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. from blog import views
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;This imports views from the blog app&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in the url path we added earlier, add some extra information&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20. urlpatterns = [
21.     path('some-random-text/', admin.site.urls),
22.     path('', views.home)
23. ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;This invariably says that when you open the link; prefix with an empty suffix; run the function named home, which you would find in the views file. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is also a good practice to give names to your url's, as you would be referencing them a lot in your HTML documents. To add a name:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20. urlpatterns = [
21.     path('some-random-text/', admin.site.urls),
22.     path('', views.home, name='home')
23. ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Save everything, and restart your server. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1sQaJYkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/72hrh1si56fayr17t83m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1sQaJYkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/72hrh1si56fayr17t83m.png" alt="Testing changes made to site; new home page"&gt;&lt;/a&gt;Ignore the empty look&lt;br&gt;
💃🕺🍾💃🕺🍾 I think we should celebrate. Go get yourself a bottle of whatever you like best, you've worked hard. &lt;br&gt;
You could go over it by creating another app and another url, and so on. Be curious. You have everything to gain!&lt;br&gt;
I'd also take a break🍟. We continue another time.&lt;br&gt;
&lt;small&gt;Project can be found &lt;a href="https://github.com/JonathanFarinloye/Beginners_Tutorial_Django"&gt;here&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Beginning Django - Lesson 1</title>
      <dc:creator>Jonathan Farinloye</dc:creator>
      <pubDate>Tue, 18 Jun 2019 01:27:52 +0000</pubDate>
      <link>https://forem.com/jonathanfarinloye/beginning-django-lesson-1-1ggb</link>
      <guid>https://forem.com/jonathanfarinloye/beginning-django-lesson-1-1ggb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This series is specifically for beginners who want to learn the Django. The Web framework based on Python. As you should know, Python is a requirement, and we'd be making use of Python v3.0+. It'd also be nice if you know some HTML and CSS. I'm not saying know it all level. Just basic knowledge.&lt;/p&gt;

&lt;p&gt;I'm also learning, so you might have some questions and I might not be able to answer immediately. However, feel free to ask questions, I'd try my best to answer.&lt;/p&gt;

&lt;p&gt;So in this lesson, we'd be learning about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installation

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;PIP&lt;/li&gt;
&lt;li&gt;Virtual Environment&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Starting a new Project&lt;/li&gt;
&lt;li&gt;Running a new Project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before starting, you should know a few things: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;a href="https://www.djangoproject.com/"&gt;Django Project&lt;/a&gt; has great documentation. You should make sure to check it out. &lt;/li&gt;
&lt;li&gt;This tutorial would be done completely on a Linux machine and should work perfectly for Linux distributions and MacOS. You might need to do a little bit of extra work if you're using Windows.&lt;/li&gt;
&lt;li&gt;All commands to be run in the terminal would start with a &lt;strong&gt;'$'&lt;/strong&gt;. The &lt;strong&gt;'$'&lt;/strong&gt; is not part of the command&lt;/li&gt;
&lt;li&gt;Feel free to skip to sections you need if you're already familiar with the previous sections.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Python
&lt;/h3&gt;

&lt;p&gt;Python needs to be installed and as mentioned earlier, Python version 3.0 or greater.&lt;br&gt;
To check if python3 is installed, open your terminal and type&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running that should open a prompt similar to this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Python 3.7.3 (default, Apr  3 2019, 05:39:12) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for information.
&amp;gt;&amp;gt;&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If it does, you're good to go. If not, you need to first install python3. You can go to the &lt;a href="https://www.python.org/"&gt;official site&lt;/a&gt; to download it and install it. If you're on Linux. You could try:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install python3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This would install the latest version of Python3.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt;PIP
&lt;/h3&gt;

&lt;p&gt;Pip is basically a package manager for python. To install it, visit the documentation &lt;a href="https://pip.pypa.io/en/latest/installing/"&gt;here&lt;/a&gt; or try:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install python3-pip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Virtual Environment
&lt;/h3&gt;

&lt;p&gt;I would suggest using a virtual environment because it allows you to basically localize your project and all the packages you use while working. To install virtualenv, open your terminal and run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo pip3 install virtualenv 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

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

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt install python3-venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that we have installed virtualenv, lets create one.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ virtualenv -p python3 myvenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

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

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3 -m venv myvenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;You can replace 'myvenv' with the name of your choice&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;To activate the virtual environment:&lt;/p&gt;

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

&lt;p&gt;To deactivate it:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;at this point, I'm getting tired. Maybe you are too. Go take a short walk🌞. I'd be here when you're back.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Django
&lt;/h3&gt;

&lt;p&gt;No? No walk? Okay. Well, to install django, first ensure that your virtualenv is active. Then run:&lt;/p&gt;

&lt;div class="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;This would download and install the Django package into your virtual environment.&lt;br&gt;
And that installs all we need to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Starting a New Project
&lt;/h2&gt;

&lt;p&gt;Our project would be named &lt;strong&gt;awesome&lt;/strong&gt; because you're awesome😉 . Feel free to give it another name, but don't forget, anywhere you see &lt;strong&gt;awesome&lt;/strong&gt;, you replace it with your project name. To create, run:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ django-admin startproject awesome
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And! BoOm💥 We have a new project named awesome.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a&gt;&lt;/a&gt;Running a Project
&lt;/h2&gt;

&lt;p&gt;To run a project, first move into the directory of the project. &lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd awesome
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then run: &lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/awesome$ python manage.py runserver
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You get something like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 unapplied migration(s). Your project may not work properly 
until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

June 17, 2019 - 17:41:50
Django version 2.2.1, using settings 'awesome.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If yes, you're doing great. Now, open your browser and visit &lt;a href="http://127.0.0.1:8000/"&gt;http://127.0.0.1:8000/&lt;/a&gt;.&lt;br&gt;
Looks like this?&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NbCkA3R6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/52jtd3hld5foka1z6gps.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NbCkA3R6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/52jtd3hld5foka1z6gps.png" alt="Django Install Successful Page"&gt;&lt;/a&gt;&lt;/p&gt;
Your project is up and running! 



&lt;p&gt;Great! I hope I didn't confuse you. Leave a comment if there's anything I should know or can help with.&lt;br&gt;
&lt;small&gt;Project can be found &lt;a href="https://github.com/JonathanFarinloye/Beginners_Tutorial_Django"&gt;here&lt;/a&gt;&lt;/small&gt;&lt;br&gt;
&lt;small&gt;Cover image by &lt;a href="https://pngtree.com"&gt;pngtree.com&lt;/a&gt;&lt;/small&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Cheers ✨✨
&lt;/h4&gt;

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