Skip to main content

Creating A New Django Blog (Setup + Introduction) | Python Django

 We have come so far in our Django journey. Till now, we've successfully created two projects, first is the textutils website, and another is our E-commerce website. Now, it's time to start our third Django project. We will be creating a blog named "Icoder" with the help of Django and the Bootstrap. In the previous tutorials, I've already covered all the basics of Django. While creating the Icoder blog, we will look at some advanced Django concepts such as authentication, authorization etc. I will use the Visual Studio IDE; feel free to use any other IDE of your choice. So, without wasting time, let's start the setup of the Icoder blog.

Step 4: Now, open a terminal in the VS code and type the below code to start the project:

django-admin startproject iCoder

Step 5: Now, we will create a blog app in the iCoder project. Get into the directory containing the manage.py file and type the below code in the VS code terminal to create the app :

python manage.py startapp blog

This is all for this tutorial, and I hope that you are enjoying this Django journey. You can ask your doubts in the QnA section.

No Source Code Associated With This Video

Steps To Open The Project In VS Code: 

Step 1: Create a directory named "Icoder" in your pc. 
Step 2: Open the Icoder folder, and do "Shift + Right Click." You will see the following screen :

Step 3: Click on the "Open with code," and the Icoder directory will get open in the VS code.

Django Blog: Project Setup & URLConfs | Python Django Tutorials In Hindi #72

We will start this tutorial by creating a file named 'requirements.txt,' and we will create a virtual environment for our project. So, make a new file called "requirements.txt" in the main icoder directory. After this, install the virtual environment by typing the below command in the existing terminal of the VS code :

pip install virtualenv

After successfully installing the virtual environment, create a new virtual environment  by typing the below code :

virtualenv myprojectenv

In the above code, we are creating a new virtual environment named "myprojectenv."  After running the above command, you will notice that a new folder named myprojectenv is created inside the main icoder directory. After this, we need to activate the virtual environment that we've just created. Get into the myprojectenv and type the below code to  activate the virtual env :

.\Scripts\activate

There is a chance that you encounter the below error after executing the above command:

.\Scripts\activate : The term '.\Scripts\activate' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the 
name, or if a path was included, verify that the path is correct and try again.
At line:1 char:2
+  .\Scripts\activate
+  ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (.\Scripts\activate:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Steps to resolve the above error:

Step 1: Head over to File--> Preferences--> Settings as shown in the below image.

Step 2: After this, search "extensions" and click on "Edit in settings.json."

Step 3: Now, we need to set the command line policies. To do so, type the below code in the settings.json file and VS code will automatically set the command line policies for you :

 "terminal.integrated.shellArgs.windows": ["-ExecutionPolicy", "Bypass"],

Restart the VS code and try to activate the virtual environment. If you've followed the above steps correctly, then your virtual environment will get activated. This tutorial ends here, and in the next tutorial, we will how to properly create and manage apps in Django.

No Source Code Associated With This Video

Django Blog: Creating Django Apps & Properly Managing Them | Python Django Tutorials In Hindi #73

In this tutorial, we will create apps for the iCoder blog. We will start by creating a new app named home. Endpoints like about, contact page, etc. will be contained inside this app. Type the below code to make the home app:

python manage.py startapp home

After this, open the views.py file of the icoder directory and type the below code :

"""iCoder URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('home.urls')),
    path('blog/', include('blog.urls')),
]

In the above code, we've created two URLs, first is for home, and the second one is for the blog app. So, whenever the user tries to access the http://127.0.0.1:8000/ then, the control will be redirected to the urls.py file of the shop app. Similarly, whenever the user attempts to access the http://127.0.0.1:8000/blog/, then the control will be sent to the urls.py file of the blog app. Now, we will map the views and URLs of the home app. Open the urls.py file of the home and type the below code:

from django.contrib import admin
from django.urls import path, include
from home import views

urlpatterns = [
    path('', views.home, name="home"),
    path('contact', views.contact, name="contact"),
    path('about', views.about, name="about"),

Now, open the views.py file of the home app and type the code given below code:

from django.shortcuts import render, HttpResponse

# Create your views here.
def home(request): 
    return HttpResponse('This is home ')

def contact(request):
    return HttpResponse("This is contact")

def about(request): 
    return HttpResponse('This is about')

Restart the development server and check whether all the endpoints for the home app are working correctly or not. Let's start mapping URLs and views for the blog app. Open the urls.py file of the blog app and type the below code:

from django.contrib import admin
from django.urls import path, include
from . import views

urlpatterns = [
    path('', views.blogHome, name="bloghome"),
    path('<str:slug>', views.blogPost, name="blogPost"),
]

In the above code, we've created a slug field for the blogPost function. Let's spend some time discussing the slug filed in Django.

Slug Field in Django : 

As we are creating a blog, so it is clear that our will contain more than one blog post. So, how can we display the requested blog post to the user? Let's assume we have a blog post with the title "Django Made Easy By Code With Harry" with a unique id=4. One way to refer to this blog post is to append the id at the end of the URL like http://127.0.0.1:8000/blog/4, or we can use http://127.0.0.1:8000/blog/Django Made Easy By Code With Harry. The second URL format looks more detailed, and here comes the concept of the slug field in Django. With the help of the slug field, we can convert the title into the slug. Now, open the views.py file of the shop app and type the below code: 

from django.shortcuts import render, HttpResponse

# Create your views here.
def blogHome(request): 
    return HttpResponse('This is  blog home. We will keep all blog posts here')

def blogPost(request, slug): 
    return HttpResponse(f'This is blogPost : {slug}')

Restart the development server and head over to the blog and type anything after the "/blog" in the URL. You will notice that the texted after "/blog" is displayed on the screen. You can also find the same in the below image :

This tutorial ends here, and in the upcoming tutorials, we will how to automatically convert the title of the blog posts into the slug. Feel free to ask your queries in the QnA section.

No Source Code Associated With This Video

Django Blog: Adding HTML Templates | Python Django Tutorials In Hindi #74

In this tutorial, we will create templates for our iCoder blog. Before getting our hands dirty by writing code, we need to make some changes in the settings of the project. Open the settings.py file and type "templates" after "DIRS." You can find the same in the below image :

Now, we are all set to start the template making for the iCoder blog. Create a new directory named "templates" in the iCoder directory. Inside the " templates" folder, we need to create two folders. The first is "blog"; this folder will contain all the templates for the blog app. Another one is "home"; all the templates for the home app will be contained inside this folder. After successfully creating these two folders create a new file named "base.html" in the templates directory. We will use this base template to use the same code in different files instead of writing the same code repeatedly. Open the base.html file and type the below code:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <title>{% block title %}   {% endblock title %}</title>
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="/">iCoder</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
              <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="/about">About</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="/contact">Contact</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="/blog">Blog</a>
            </li>
          </ul>
          <form class="form-inline my-2 my-lg-0">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
          </form>
        </div>
      </nav>

      {% block body %}  {% endblock body %}

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
  </body>
</html>

After this, go to templates-->blog, and create the following files :

  1. blogHome.html: We will use this template to display the home page of the blog.
  2. blogPost.html: This template will be responsible for displaying the blog posts.

Now, open the blogHome.html file and type the below code :

{% extends 'base.html' %}

{% block title %} BlogHome {% endblock title %}

{% block body %}

 {% endblock %}

In the above code, we are extending the code of the base.html file. Now, open the blogpost.html file and type the below code: 

{% extends 'base.html' %}

{% block title %} Blogpost{% endblock title %}

{% block body %}

 {% endblock %}

Now, we will create templates for the home app. So, go to templates-->home and create the following files:

  1. home.html: We will use this template to display the home page of the home app.
  2. about.html: We will create the about page of the iCoder blog in this template.
  3. contact.html: This template will be used to display the contact page of the iCoder blog.

Open the home.html file and type the below code:

{% extends 'base.html' %}

{% block title %} Home{% endblock title %}

{% block body %}

 {% endblock %}

Type the below code in the about.html file :

{% extends 'base.html' %}

{% block title %} About{% endblock title %}

{% block body %}

 {% endblock %}

Type the below code in the contact.html file :

{% extends 'base.html' %}

{% block title %} Contact{% endblock title %}

{% block body %}

 {% endblock %}

Restart the development server and make sure that all the endpoints are working correctly.

No Source Code Associated With This Video

Django 3 Blog: Creating Migrations & Superusers | Python Django Tutorials In Hindi #76

In this tutorial, we will create superuser and migrations for our iCoder blog. First of all, restart the development server, and you will see the following warnings :

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth

By showing the above warning, Django is trying to tell us that we've not created the required tables in the database. Execute the below command to make the required tables and get rid of the warnings :

python manage.py migrate

Start the development server again, and you will notice that no warnings are displayed on the terminal. With this, we are all set to create a superuser. So, without wasting time, open the terminal in the Vs code and fire the below command :

python manage.py createsuperuser

After executing the above command, Django requires you to set up the login credentials. Submit all the login credentials carefully, and restart the development server. Now, go to http://127.0.0.1:8000/admin/. You will see the following screen :

So hat's how we created the superuser for our iCoder blog within seconds. In the upcoming tutorials, we will see how to make models and write the changes in the database.

No Source Code Associated With This Video

Django 3 Blog: Creating "Contact Us" Model | Python Django Tutorials In Hindi #77

In this tutorial, we will create a "Contact Us" model for the home app of the iCoder blog. We made two apps in our previous tutorials, but to consider the apps in the project, Django requires us to specify the app names in the INSTALLED_APPS list as follows in settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'home.apps.HomeConfig', 
    'blog.apps.BlogConfig',
]

With this, we are all set to start the creation of the "Contact Us" model in the database. Without wasting time, open the models.py file of the home app and type the below code:

from django.db import models

# Create your models here.
class Contact(models.Model):
     sno= models.AutoField(primary_key=True)
     name= models.CharField(max_length=255)
     phone= models.CharField(max_length=13)
     email= models.CharField(max_length=100)
     content= models.TextField()
     timeStamp=models.DateTimeField(auto_now_add=True, blank=True)

Restart the development server and head over to http://127.0.0.1:8000/contact, and you will see the following screen :

This tutorial ends here, and in the upcoming tutorial, we will see how to handle post requests in Django's views.

No Source Code Associated With This Video

Now, open the admin.py file of the home app and register the Contact model by typing the below code:

from django.contrib import admin
from .models import Contact

# Register your models here.
admin.site.register(Contact)

Now, we need to make the migrations and apply the changes in the database. So, run the below commands one by one :

python manage.py makemigrations
python manage.py migrate

Restart the development server and go to the admin panel of the iCoder blog. You will see the following screen:

In the above image, you can see that we've successfully created a Contact model for the home app. Now, we will design a contact form with the help of the Bootstrap to take the input from the user. Click here to go to the official website of the Bootstrap and select a form of your choice, or you can copy the below code and paste in the contact.html file of the home template directory.

{% extends 'base.html' %}

{% block title %} Contact{% endblock title %}

{% block body %}
<div class="container my-3">
<h3>Contact iCoder Admin</h3>
<form action="/contact" method="post">
{% csrf_token %}
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" class="form-control" id="name" name="name"aria-describedby="name">
  </div>

  <div class="form-group">
    <label for="email">Email address</label>
    <input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp">
    <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
  </div>

  <div class="form-group">
    <label for="phone">Phone Number</label>
    <input type="tel" class="form-control" id="phone" name="phone">
  </div>

  <div class="form-group">
    <label for="content">Describe your issue :</label>
    <textarea class="form-control" name="content" id="content" cols="30" rows="5"></textarea>
  </div>


  <button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
 {% endblock %}

Django 3 Blog: Handling Post Request in a Django View | Python Django Tutorials In Hindi #78

In this tutorial, we will see how to handle a post request in the Django view. To manage the post requests, we need to make some changes in the views of the home app. So, open the views.py file of the home app and type the below code:

from home.models import Contact

def contact(request):
    if request.method=="POST":
        name=request.POST['name']
        email=request.POST['email']
        phone=request.POST['phone']
        content =request.POST['content']
        contact=Contact(name=name, email=email, phone=phone, content=content)
        contact.save()
    return render(request, "home/contact.html")

Let's understand the above one line at a time. First of all, we've imported the Contact model from the database in the views.py file. Then, we've created a function named contact in which we are storing all the user input in different variables. Now, restart the development server and go to the contact page. Submit the form and open the admin panel. You will see that the response submitted by you is displayed on the admin panel. I submitted three responses, and in the below image, you can see that all the response objects are successfully displayed on the back-end.

We've successfully handled the post request in the back-end, but the format, i.e., Contact object(object_number), looks ugly, and it is hard to identify various responses in this format. So, let's change this format. Open the models.py file of the home app and type the below code :

class Contact(models.Model):
     sno= models.AutoField(primary_key=True)
     name= models.CharField(max_length=255)
     phone= models.CharField(max_length=13)
     email= models.CharField(max_length=100)
     content= models.TextField()
     timeStamp=models.DateTimeField(auto_now_add=True, blank=True)

     def __str__(self):
          return "Message from " + self.name + ' - ' + self.email

Reload the server and go to the admin panel after submitting another response on the contact page. You will notice that that the format of the displaying contact objects is changed successfully. You can also find the same in the below image:

 

No Source Code Associated With This Video

Django Mesasges Framework: Showing Messages in Django blog | Python Django Tutorials In Hindi #79

In the previous tutorial, we saw how to handle a post request in the back-end of the iCoder blog. But, how will the user get to know whether the contact form is submitted successfully or not? We need to show a failure or success message to the user depending upon the status of the contact form. We will use the message framework of Django to display a message whenever the user submits a contact form on the iCoder blog. With this amazing messaging system of Django, we can pop a one-time-notification (flash message) after processing a form. To use the Django message framework, we need to make some changes in the settings of our project. So, open the settings.py file and follow the steps given below :

Output :

In the above image, you can see that an error message is displayed when we tried to submit the empty form. So, that's how you can display one-time-notifications on your website with the help of the Django message framework. I hope that the concept of the message framework is crystal clear to you. You can ask your queries in the QnA section.

No Source Code Associated With This Video

Step 1: Import the message framework by typing the below code in the settings.py file:

import os
from django.contrib.messages import constants as messages

Step 2: Set the below message tag to display an error message:

MESSAGE_TAGS = {
    messages.ERROR:'danger'
}

Now, we will use the Boostrap dismissible alert to display an alert message So, open the base.html file and type the below code:

     {% for message in messages  %}            
      <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <strong>Message : </strong> {{ message }}
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
      {% endfor %}    

Restart the development server and head over to http://127.0.0.1:8000, and you will notice that the error message is displayed on every page of the iCoder blog. But, we want to display the message only when the user submits the form. To do so, we need to make some changes in the views of the home app. So, open the views.py file and type the below code:

def contact(request):
    if request.method=="POST":
        name=request.POST['name']
        email=request.POST['email']
        phone=request.POST['phone']
        content =request.POST['content']
        if len(name)<2 or len(email)<3 or len(phone)<10 or len(content)<4:
            messages.error(request, "Please fill the form correctly")
        else:
            contact=Contact(name=name, email=email, phone=phone, content=content)
            contact.save()
            messages.success(request, "Your message has been successfully sent")
    return render(request, "home/contact.html")

In the above code, we're using an if loop to check whether a post request is made or not. So the message will be displayed only when a post request is made on the contact form. After this, we're using another if block to verify that all the details are filled correctly in the form, and the user is not submitting an empty block of the form. In Django, we use message.error to display an error message and message.success to display a success message. In the end, we are saving the contact variable and displaying a success message. Now, reload the server and submit the contact form by filling all the required details correctly. You will see the following screen :

I filled all the details correctly, and you can see that form is submitted successfully with a success message poped on the user's screen. Let's see what happens if we try to submit an empty block in the form :

Input :

Django 3 Blog: Designing Blog Page & Displaying Blog Posts | Python Django Tutorials In Hindi #80

We will use Bootstrap to design the home page and the blogposts page of the iCoder blog. First of all, we will design the home page of our blog. I am using Bootstrap jumbotron on the home page. You can get the code from the official website, or you can use the code given below. Open the home.html file and type the below code:

<div class="container">
<div class="jumbotron my-3">
  <h1 class="display-4">Welcome to iCoder!</h1>
  <p class="lead">This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
  <hr class="my-4">
  <p>It uses utility classes for typography and spacing to space content out within the larger container.</p>
  <a class="btn btn-primary btn-lg" href="/blog" role="button">Go to Blog</a>
  </div>
</div>

You will see the following screen on restarting the server :

We've added a "Go to Blog" button inside the jumbotron. On clicking this button, the user will get redirected to the blog section of the iCoder blog. We will also show the popular blog posts on the home page, and here is the code for it :

<div class="container">
<h2>Popular Blogposts</h2>
<div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 my-4 position-relative">
        <div class="col p-4 d-flex flex-column position-static">
          <strong class="d-inline-block mb-2 text-primary">World</strong>
          <h3 class="mb-0">Featured post</h3>
          <div class="mb-1 text-muted">Nov 12</div>
          <p class="card-text mb-auto">This is a wider card with supporting text below as a natural lead-in to additional content.</p>
          <a href="#" class="stretched-link">Continue reading</a>
        </div>
   <div class="col-auto d-none d-lg-block">
          <svg class="bd-placeholder-img" width="200" height="250" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: Thumbnail"><title>Placeholder</title><rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text></svg>
        </div>     
      </div>
      </div>

Type the above code in the home.html file after the jumbotron code. Reload the server, and you will get the following the output :

In further tutorials, I will show you how to fetch the popular blog posts from the database. We will now move on to the designing of the blog section of the iCoder app. Open the blogHome.html file and type the below code :

{% extends 'base.html' %}

{% block title %} BlogHome {% endblock title %}
{% block blogactive %} active {% endblock blogactive %} 


{% block body %}
<div class="container my-3">
    <h2>Coding Articles by iCoder</h2>
    <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 my-4 position-relative">
        <div class="col p-4 d-flex flex-column position-static">
            <strong class="d-inline-block mb-2 text-primary">World</strong>
            <h3 class="mb-0">Featured post</h3>
            <div class="mb-1 text-muted">Nov 12</div>
            <p class="card-text mb-auto">This is a wider card with supporting text below as a natural lead-in to additional content.</p>
            <div class="my-2">
            	<a href="/blog/blogpost" role="button" class="btn btn-primary">Continue reading</a>
            </div>
            
        </div>
        <div class="col-auto d-none d-lg-block">
            <svg class="bd-placeholder-img" width="200" height="250" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: Thumbnail">
                <title>Placeholder</title>
                <rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text>
            </svg>
        </div>
    </div>
 {% endblock %}

Now, head over to http://127.0.0.1:8000/blog/, and you will see the following screen:

This is all for this tutorial, and in the next tutorial, we will develop a model to store the blog posts in the database so that we can display the blog posts on the home and the blog page.

No Source Code Associated With This Video

Django 3 Blog: Creating Blog Model to Store Blog Posts | Python Django Tutorials In Hindi #81

Till now, in the iCoder blog, we've successfully designed the home page and the blog post page of the blog section. To show any blog post on the blog, we need to store the blogs in the database. Therefore, now we will create a blog model to fetch the blog posts from the database. Open the models.py file of the blog app and type the below code :

from django.db import models

class Post(models.Model):
    sno=models.AutoField(primary_key=True)
    title=models.CharField(max_length=255)
    author=models.CharField(max_length=14)
    slug=models.CharField(max_length=130)
    timeStamp=models.DateTimeField(blank=True)
    content=models.TextField()

    def __str__(self):
        return self.title + " by " + self.author

Now, we need to apply the changes in the database, so open the terminal of your IDE and execute the commands given below one at a time:

python manage.py makemigrations
python manage.py migrate

Restart the development server and go to the admin panel. You will see a screen like this:

Click on the Posts and create a blog post by filling all the required details. With this, we've successfully stored a blog post in the database. Our next step is to fetch and display the blog post on the blog app. To do so, we need to make some changes in the blog views. So, open the views.py file and type the below code:

def blogHome(request): 
    allPosts= Post.objects.all()
    context={'allPosts': allPosts}
    return render(request, "blog/blogHome.html", context)

In the above code, we are storing all the blog posts in a variable named allPosts and then rendering this variable into the template with the help of a context dictionary. After this, open the blogHome.html file and type the below code:

{% extends 'base.html' %}

{% block title %} BlogHome {% endblock title %}
{% block blogactive %} active {% endblock blogactive %} 


{% block body %}
<div class="container my-3">
    <h2>Coding Articles by iCoder</h2>
    {% for post in allPosts  %}
    <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 my-4 position-relative">
        <div class="col p-4 d-flex flex-column position-static">
            <strong class="d-inline-block mb-2 text-primary">Article  by {{post.author}}</strong>
            <h3 class="mb-0">{{post.title}}</h3>
            <div class="mb-1 text-muted">{{post.datetime}}</div>
            <p class="card-text mb-auto">{{post.content| truncatechars:500}}</p>
            <div class="my-2">
            	<a href="/blog/{{post.slug}}" role="button" class="btn btn-primary">Continue reading</a>
            </div>
            
        </div>
        <div class="col-auto d-none d-lg-block">
            <svg class="bd-placeholder-img" width="200" height="250" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: Thumbnail">
                <title>Placeholder</title>
                <rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text>
            </svg>
        </div>
        </div>

        {% endfor %}
    </div>
 {% endblock %}

In the above code, we are using the truncate template tag to display some part of the blog content on the home page. 

truncatechars syntax :
{{ value|truncatechars: no of characters}}

We will display only 500 characters on the home page, and the remaining will be displayed on the blogpost page once the user clicks on the "Continue Reading" button. We are all set to display the blog posts. Restart the development server and head over to http://127.0.0.1:8000/blog/. You will notice that the blog posts are displayed on the home page. I added two blog posts in the back-end, and here is the output :

So, that's how we can easily fetch and display the blog posts on a blog website. This is all for this tutorial, and in the next tutorial, we will write code to display the complete blog post on clicking the Continue reading button. 

Django 3 Blog: Designing the BlogPost Page | Python Django Tutorials In Hindi #82

Download the Source code so far here.

In the previous tutorial, we saw how to fetch and display the blog posts on the home page of the iCoder blog. We will now write code to display blog posts separately on the blog post section of our blog. Open the views.py file of the blog app and type the below code :

def blogPost(request, slug): 
    post=Post.objects.filter(slug=slug).first()
    context={"post":post}
    return render(request, "blog/blogPost.html", context)

Restart the server and click on the "Continue Reading" button of any blog post, and you will see that the overall content is displayed successfully. You can also find the same in the below image :

This tutorial ends here, and in the next tutorial, we will create a search functionality for our iCoder blog.

Code as described/written in the video


Source code so far can be downloaded as zip from description

In the above code, we are storing the blog post requested by user in a variable named post by filtering the requested blog post with the slug. After this, we are rendering the post variable in the blogPost template with a context dictionary. Now, we need to make some changes in the template, so open the blogPost.html and type the below code :

{% extends 'base.html' %}

{% block title %} Blogpost{% endblock title %}

{% block body %}
<div class="container my-3">
<div class="blog-post">
        <h2 class="blog-post-title">{{post.title}}</h2>
        <p class="blog-post-meta">{{post.timeStamp}} by <a href="#">{{post.author}}</a></p>

        <p>{{post.content}}</p>
        <hr>
      </div>
      </div>
 {% endblock %}

Django 3 Blog: Creating Search Functionality | Python Django Tutorials In Hindi #83

Suppose you've added more than 500 blog posts on the iCoder blog, and now you want to see only python related articles. What will you do? Will you visit every article one by one? Of course, this is not the best approach to search within the blog posts. Therefore, we will now include search functionality on our blog website. We will use the concept of Django icontains to search the user's query in the title of the blog post. If the query is matched from the title, we will display the blog by rendering it through a search template. Django icontains is used to check if a string or query matches with a value in the database field. Enough talk! Open the urls.py file of the home app and include the following path :

  path('search', views.search, name="search"),

After this, type the below code in the views.py file of the home app:

def search(request):
    query=request.GET['query']
    allPosts= Post.objects.filter(title__icontains=query)
    params={'allPosts': allPosts}
    return render(request, 'home/search.html', params)

In the above code, we are storing the string searched by the user in a query variable, and then we are filtering all the posts in which the title field contains the query. In the final step, we're rendering the allPosts variable to the search template with the params dictionary's help. Now create a new file named search.html in the template directory of the home app. Open the search.html file and type the below code :

{% extends 'base.html' %}

{% block title %} Search Results {% endblock title %}
{% block blogactive %} active {% endblock blogactive %} 


{% block body %}
<div class="container my-3">
    <h2>Search results : </h2>
    {% for post in allPosts  %}
    <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 my-4 position-relative">
        <div class="col p-4 d-flex flex-column position-static">
            <strong class="d-inline-block mb-2 text-primary">Article  by {{post.author}}</strong>
            <h3 class="mb-0">{{post.title}}</h3>
            <div class="mb-1 text-muted">{{post.datetime}}</div>
            <p class="card-text mb-auto">{{post.content| truncatechars:500}}</p>
            <div class="my-2">
            	<a href="/blog/{{post.slug}}" role="button" class="btn btn-primary">Continue reading</a>
            </div>
            
        </div>
        <div class="col-auto d-none d-lg-block">
            <svg class="bd-placeholder-img" width="200" height="250" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: Thumbnail">
                <title>Placeholder</title>
                <rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text>
            </svg>
        </div>
        </div>

        {% endfor %}
    </div>
 {% endblock %}

With this, we've successfully created the search functionality for our iCoder blog. Type any string in the search bar and check whether the search functionality is working correctly or not. I searched for "Test Title 2" and here is the output :

That's how we created a basic search function for our blog, and in the upcoming tutorial, we will improve the search functionality. You can ask your doubts in the QnA section.

Django 3 Blog: Improving Search Functionality | Python Django Tutorials In Hindi #84

In the previous tutorial, we created a search functionality, and now it's time to improve that search functionality to provide a better user experience. Before starting the logic development for the search functionality, start the server and search any random keyword in the search bar. What happens? If the query matches the blog title, then the posts are displayed, but we are displaying an empty page if the query does not match with the database field. This is not a good practice, and we should create something to show the user that the query does not match anything. In the below image, you can see that I searched for "Java" and a blank page is displayed:

To fix this issue, we need to make some changes in the views of the home app. So, open the views.py file and type the below code :

def search(request):
    query=request.GET['query']
    if len(query)>78:
        allPosts=Post.objects.none()
    else:
        allPostsTitle= Post.objects.filter(title__icontains=query)
        allPostsAuthor= Post.objects.filter(author__icontains=query)
        allPostsContent =Post.objects.filter(content__icontains=query)
        allPosts=  allPostsTitle.union(allPostsContent, allPostsAuthor)
    if allPosts.count()==0:
        messages.warning(request, "No search results found. Please refine your query.")
    params={'allPosts': allPosts, 'query': query}
    return render(request, 'home/search.html', params)

Let's see what logic we've applied in the above code. First of all, we are checking if the query's length is more than 78 characters or not. We will only search the query if the query's length is less than 78 characters to prevent the database from getting filled with useless and long queries. If the query's length is greater than 78 characters, then we will return an error message. The else loop will get executed whenever the length of the query is less than 78 characters. We are checking if the query matches the blog title, author or content inside the else loop. If the query matches any one of the provided database fields, we will display the blog posts. Now, open the search.html file and type the below code :

{% extends 'base.html' %}

{% block title %} Search Results {% endblock title %}
{% block blogactive %} active {% endblock blogactive %} 


{% block body %}
<div class="container my-3">
    <h2>Search results : </h2>
    {% if allPosts|length < 1 %}
   <p>No search results</p>
    Your search query : <b>{{query}}</b> did not match any documents. <br>
    Suggestions:
    <ul>
    <li>Make sure that all words are spelled correctly.</li>
    <li>Try more general keywords.</li>
   <li> Try fewer keywords.</li>
   <li> Try different keywords.</li>
    </li>
    </ul>


    {% endif %}
    {% for post in allPosts  %}
    <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 my-4 position-relative">
        <div class="col p-4 d-flex flex-column position-static">
            <strong class="d-inline-block mb-2 text-primary">Article  by {{post.author}}</strong>
            <h3 class="mb-0">{{post.title}}</h3>
            <div class="mb-1 text-muted">{{post.datetime}}</div>
            <p class="card-text mb-auto">{{post.content| truncatechars:500}}</p>
            <div class="my-2">
            	<a href="/blog/{{post.slug}}" role="button" class="btn btn-primary">Continue reading</a>
            </div>
            
        </div>
        <div class="col-auto d-none d-lg-block">
            <svg class="bd-placeholder-img" width="200" height="250" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: Thumbnail">
                <title>Placeholder</title>
                <rect width="100%" height="100%" fill="#55595c"></rect><text x="50%" y="50%" fill="#eceeef" dy=".3em">Thumbnail</text>
            </svg>
        </div>
        </div>

        {% endfor %}
    </div>
 {% endblock %}

Now, restart the development server and check whether the search functionality is working correctly or not.

Input: "Django" 

Output

You can see that I searched for "Django" and it matches the blog content.

Input: "Java tutorials"

Output:

So, you can see that our search functionality is working great. This is all for this tutorial, and I will see you next time!

Django 3 Blog: Authentication & Authorization Tutorial | Python Django Tutorials In Hindi #85

In this tutorial, we will discuss the concept of authentication and authorization in Django. But first of all, why are we even bothered about the authentication and authorization. We are creating a blog website, and there can be multiple users on a blog website. Suppose you signup on your favourite blog website, but you got to know that anybody can log in to your account without your permission. Will you ever use that website again? Here the concept of authentication comes into the picture. We need to make sure that only the real user gets access to the account. Let's take another scenario, where anybody can make changes to your blog posts without even logging into your account. This is the case where we will use the concept of authorization. 

What Is Not Included?

  1. Django's authentication system aims to be very generic and doesn't provide some features commonly found in web authentication systems.
  2. Solutions for some of these common problems have been in third-party packages : 
  • Password strength checking 
  • Throttling of login attempts
  • Authentication against the third party
  • Object-level permissions

Why Use Django User Authentication :

  • It's better to use the existing built-in boilerplate than to reinvent the wheel.
  • We will use the Django authentication system to create users who can sign up and comment on the iCoder blog.
  • The Django authentication system handles both authentication and authorization.

Difference Between Authentication And Authorization :

  • Usually, the term authentication refers to both the task, but there is a slight difference between these two terms.
  • Authentication verifies a user who they claim to be, and authorization determines what an authenticated user is allowed to do.

What has the Django authentication system got for us? 

The auth system consists of  :

  • Users
  • Permissions: Binary(yes/no) flags designation whether a user may perform a certain task.
  • Groups: A generic way of applying labels and permissions to more than one user.
  • A configurable password hashing system.
  • Forms and view tool for logging in users or restricting content.
  • A pluggable backend system.

Django 3 Blog: Creating Users in Django | Python Django Tutorials In Hindi #86

In the previous tutorial, we talked about the concept of authentication in Django. Now, it's time to create a user on our iCoder blog. We've already created the signup form in our last tutorial, and now we will handle the user's input in the backend of our blog. Set the action and method of the signup form by typing the below code in base.html file :

<form action= "/signup" method='post'>

Now, we will create a function to process the user's request in the back-end. Type the below code in the views.py file of the home app :

def handleSignUp(request):
    if request.method=="POST":
        # Get the post parameters
        username=request.POST['username']
        email=request.POST['email']
        fname=request.POST['fname']
        lname=request.POST['lname']
        pass1=request.POST['pass1']
        pass2=request.POST['pass2']

        # check for errorneous input
        
        # Create the user
        myuser = User.objects.create_user(username, email, pass1)
        myuser.first_name= fname
        myuser.last_name= lname
        myuser.save()
        messages.success(request, " Your iCoder has been successfully created")
        return redirect('home')

    else:
        return HttpResponse("404 - Not found")

Let's understand the above code line by line. First of all, we're checking if the user has made a post request to make a new account on the blog. After this, we're storing all the inputs from the user in different variables. We've used the create_user() function of Django to create a new user. create_user() takes three arguments:

  • username
  • email
  • password

In the end, we're storing the newly created user with the help of myuser.save(). If the user is created successfully, we will display a success message by using Django's message framework, and the user will be redirected to the home page. Define the path given below in the urls.py file of the home app :

path('signup', views.handleSignUp, name="handleSignUp"),

This is all we need to do to create a user on our iCoder blog. Let's check if everything is working correctly or not. 

Input :

Output :

In the above image, you can see that a success message is displayed, which indicates that the user has been created successfully. And that's how you can easily create a user by using the create_user() functionality of Django.

Code base.html as described/written in the video:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <title>{% block title %}   {% endblock title %}</title>
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="/">iCoder</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item {% block homeactive %}  {% endblock homeactive %}">
              <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item {% block aboutactive %}  {% endblock aboutactive %}" >
              <a class="nav-link" href="/about">About</a>
            </li>
            <li class="nav-item {% block contactactive %}  {% endblock contactactive %} ">
              <a class="nav-link" href="/contact">Contact</a>
            </li>
            <li class="nav-item {% block blogactive %}  {% endblock blogactive %} ">
              <a class="nav-link" href="/blog">Blog</a>
            </li>
            
          </ul>
          <form method="get" action="/search"class="form-inline my-2 my-lg-0 mx-3">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="query" id="query">
            <button class="btn btn-outline-success my-2 my-sm-0 " type="submit">Search</button>
            <a href="/admin" role="button" target="_blank" class="btn btn-outline-success m-2 my-sm-0"> Admin Panel </a>
          </form>

               <!-- Button to  trigger SignUp modal -->

  <!-- Button to  trigger Login modal -->
<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#loginModal">
Login
</button>

<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#signupModal">
SignUp
</button>


        </div>
      </nav>
      {% for message in messages  %}            
      <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <strong>Message : </strong> {{ message }}
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
      {% endfor %}    



 

<!-- SignUp Modal -->
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="signupModalTitle">SignUp Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action= "/signup" method='post'>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="username" name="username" placeholder="Choose a unique username">
  </div>
  <div class="form-group">
    <label for="fname">First Name</label>
    <input type="text" class="form-control" id="fname" name="fname" placeholder="Enter Your First Name">
  </div>
  <div class="form-group">
    <label for="lname">Last Name</label>
    <input type="text" class="form-control" id="lname" name="lname" placeholder="Enter Your Last Name">
  </div>
  <div class="form-group">
    <label for="email">Email address</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="name@example.com">
  </div>
  <div class="form-group">
    <label for="pass1">Choose a password</label>
    <input type="password" class="form-control" id="pass1" name="pass1" placeholder="Choose Your Password">
  </div>
  <div class="form-group">
    <label for="pass2">Confirm Password</label>
    <input type="password" class="form-control" id="pass2" name="pass2" placeholder="Enter your password again">
  </div>
 

        {% csrf_token %}
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
      <div class="modal-footer">
      </div>
    </div>
  </div>
</div>






      {% block body %}  {% endblock body %}

<!-- Login Modal -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="loginModalTitle">Login Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="loginusername" name="loginusername" placeholder="Choose a unique username">
  </div>
  <div class="form-group">
    <label for="pass">Enter your password </label>
    <input type="password" class="form-control" id="pass" name="pass" placeholder="Enter your password ">
  </div>
 
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
       <div class="modal-footer">
      </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
  </body>
</html>

Code home/views.py as described/written in the video:

from django.shortcuts import render, HttpResponse, redirect
from home.models import Contact
from django.contrib import messages 
from django.contrib.auth.models import User 
from blog.models import Post
def home(request): 
    return render(request, "home/home.html")

def contact(request):
    if request.method=="POST":
        name=request.POST['name']
        email=request.POST['email']
        phone=request.POST['phone']
        content =request.POST['content']
        if len(name)<2 or len(email)<3 or len(phone)<10 or len(content)<4:
            messages.error(request, "Please fill the form correctly")
        else:
            contact=Contact(name=name, email=email, phone=phone, content=content)
            contact.save()
            messages.success(request, "Your message has been successfully sent")
    return render(request, "home/contact.html")

def search(request):
    query=request.GET['query']
    if len(query)>78:
        allPosts=Post.objects.none()
    else:
        allPostsTitle= Post.objects.filter(title__icontains=query)
        allPostsAuthor= Post.objects.filter(author__icontains=query)
        allPostsContent =Post.objects.filter(content__icontains=query)
        allPosts=  allPostsTitle.union(allPostsContent, allPostsAuthor)
    if allPosts.count()==0:
        messages.warning(request, "No search results found. Please refine your query.")
    params={'allPosts': allPosts, 'query': query}
    return render(request, 'home/search.html', params)

def handleSignUp(request):
    if request.method=="POST":
        # Get the post parameters
        username=request.POST['username']
        email=request.POST['email']
        fname=request.POST['fname']
        lname=request.POST['lname']
        pass1=request.POST['pass1']
        pass2=request.POST['pass2']

        # check for errorneous input
        
        # Create the user
        myuser = User.objects.create_user(username, email, pass1)
        myuser.first_name= fname
        myuser.last_name= lname
        myuser.save()
        messages.success(request, " Your iCoder has been successfully created")
        return redirect('home')

    else:
        return HttpResponse("404 - Not found")


def about(request): 
    return render(request, "home/about.html")

Code home/urls.py as described/written in the video:

from django.contrib import admin
from django.urls import path, include
from home import views

urlpatterns = [
    path('', views.home, name="home"),
    path('contact', views.contact, name="contact"),
    path('about', views.about, name="about"),
    path('search', views.search, name="search"),
    path('search', views.search, name="search"),
    path('signup', views.handleSignUp, name="handleSignUp"),
]

Django 3 Blog: Validating SignUp Form | Python Django Tutorials In Hindi #87

In the previous tutorial, we saw how we could create a user in our iCoder blog. We were taking input from the user in a signup form, but that signup form is incomplete because it does not check whether all the form fields are filled or not. So, let's see how we can validate the signup form of our iCoder blog. We will use some if-else conditions in the views of the home app. So, open the views.py file and type the below code:

from django.shortcuts import redirect

def handleSignUp(request):
    if request.method=="POST":
        # Get the post parameters
        username=request.POST['username']
        email=request.POST['email']
        fname=request.POST['fname']
        lname=request.POST['lname']
        pass1=request.POST['pass1']
        pass2=request.POST['pass2']

        # check for errorneous input
        if len(username)<10:
            messages.error(request, " Your user name must be under 10 characters")
            return redirect('home')

        if not username.isalnum():
            messages.error(request, " User name should only contain letters and numbers")
            return redirect('home')
        if (pass1!= pass2):
             messages.error(request, " Passwords do not match")
             return redirect('home')
        
        # Create the user
        myuser = User.objects.create_user(username, email, pass1)
        myuser.first_name= fname
        myuser.last_name= lname
        myuser.save()
        messages.success(request, " Your iCoder has been successfully created")
        return redirect('home')

    else:
        return HttpResponse("404 - Not found")

In the above code, first of all, we are storing all the user's input in appropriate variables. Then, we've used three if conditions:

  1. len(username)<10: If the length of the user name is less than 10, then we will display an error message, and the user will be redirected to the home page for which we've used the redirect shortcut of the Django.
  2. username.isalnum(): We are allowing only alphanumeric username. Here, we are using the isalnum() function of python to make sure that the username contains only alphabets and numbers.
  3. In the last loop, we're checking if password 1 equals to password 2 or not. 

If all the three loops are passed, then only we will create the user otherwise, we will not allow the user to signup on the iCoder blog. After this, open the base.html file and type "required" at the end of every input field in the signup form. You can also see the syntax in the below image:

Now, reload the server and check if the signup form is validating the input or not. In the below image, you can see that the signup form is not accepting the empty fields.

I tried to provide a user name of fewer than 10 characters, and here is the output :

So that's how we easily validated the user input in the signup form.

Code home/views.py as described/written in the video:

from django.shortcuts import render, HttpResponse, redirect
from home.models import Contact
from django.contrib import messages 
from django.contrib.auth.models import User 
from blog.models import Post
def home(request): 
    return render(request, "home/home.html")

def contact(request):
    if request.method=="POST":
        name=request.POST['name']
        email=request.POST['email']
        phone=request.POST['phone']
        content =request.POST['content']
        if len(name)<2 or len(email)<3 or len(phone)<10 or len(content)<4:
            messages.error(request, "Please fill the form correctly")
        else:
            contact=Contact(name=name, email=email, phone=phone, content=content)
            contact.save()
            messages.success(request, "Your message has been successfully sent")
    return render(request, "home/contact.html")

def search(request):
    query=request.GET['query']
    if len(query)>78:
        allPosts=Post.objects.none()
    else:
        allPostsTitle= Post.objects.filter(title__icontains=query)
        allPostsAuthor= Post.objects.filter(author__icontains=query)
        allPostsContent =Post.objects.filter(content__icontains=query)
        allPosts=  allPostsTitle.union(allPostsContent, allPostsAuthor)
    if allPosts.count()==0:
        messages.warning(request, "No search results found. Please refine your query.")
    params={'allPosts': allPosts, 'query': query}
    return render(request, 'home/search.html', params)

def handleSignUp(request):
    if request.method=="POST":
        # Get the post parameters
        username=request.POST['username']
        email=request.POST['email']
        fname=request.POST['fname']
        lname=request.POST['lname']
        pass1=request.POST['pass1']
        pass2=request.POST['pass2']

        # check for errorneous input
        if len(username)<10:
            messages.error(request, " Your user name must be under 10 characters")
            return redirect('home')

        if not username.isalnum():
            messages.error(request, " User name should only contain letters and numbers")
            return redirect('home')
        if (pass1!= pass2):
             messages.error(request, " Passwords do not match")
             return redirect('home')
        
        # Create the user
        myuser = User.objects.create_user(username, email, pass1)
        myuser.first_name= fname
        myuser.last_name= lname
        myuser.save()
        messages.success(request, " Your iCoder has been successfully created")
        return redirect('home')

    else:
        return HttpResponse("404 - Not found")



   

    return HttpResponse("login")

def hanldeLogout(request):
    return HttpResponse("logout")


def about(request): 
    return render(request, "home/about.html")

Code base.html as described/written in the video:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <title>{% block title %}   {% endblock title %}</title>
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="/">iCoder</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item {% block homeactive %}  {% endblock homeactive %}">
              <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item {% block aboutactive %}  {% endblock aboutactive %}" >
              <a class="nav-link" href="/about">About</a>
            </li>
            <li class="nav-item {% block contactactive %}  {% endblock contactactive %} ">
              <a class="nav-link" href="/contact">Contact</a>
            </li>
            <li class="nav-item {% block blogactive %}  {% endblock blogactive %} ">
              <a class="nav-link" href="/blog">Blog</a>
            </li>
            
          </ul>
          <form method="get" action="/search"class="form-inline my-2 my-lg-0 mx-3">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="query" id="query">
            <button class="btn btn-outline-success my-2 my-sm-0 " type="submit">Search</button>
            <a href="/admin" role="button" target="_blank" class="btn btn-outline-success m-2 my-sm-0"> Admin Panel </a>
          </form>

               <!-- Button to  trigger SignUp modal -->

  <!-- Button to  trigger Login modal -->
<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#loginModal">
Login
</button>

<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#signupModal">
SignUp
</button>


        </div>
      </nav>
      {% for message in messages  %}            
      <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <strong>Message : </strong> {{ message }}
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
      {% endfor %}    



 

<!-- SignUp Modal -->
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="signupModalTitle">SignUp Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action= "/signup" method='post'>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="username" name="username" placeholder="Choose a unique username" required>
  </div>
  <div class="form-group">
    <label for="fname">First Name</label>
    <input type="text" class="form-control" id="fname" name="fname" placeholder="Enter Your First Name" required>
  </div>
  <div class="form-group">
    <label for="lname">Last Name</label>
    <input type="text" class="form-control" id="lname" name="lname" placeholder="Enter Your Last Name" required>
  </div>
  <div class="form-group">
    <label for="email">Email address</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="name@example.com" required>
  </div>
  <div class="form-group">
    <label for="pass1">Choose a password</label>
    <input type="password" class="form-control" id="pass1" name="pass1" placeholder="Choose Your Password" required>
  </div>
  <div class="form-group">
    <label for="pass2">Confirm Password</label>
    <input type="password" class="form-control" id="pass2" name="pass2" placeholder="Enter your password again" required>
  </div>
 

        {% csrf_token %}
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
      <div class="modal-footer">
      </div>
    </div>
  </div>
</div>






      {% block body %}  {% endblock body %}

<!-- Login Modal -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="loginModalTitle">Login Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action="/login" method="POST">
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="loginusername" name="loginusername" placeholder="Enter your username "required>
  </div>
  <div class="form-group">
    <label for="pass">Enter your password </label>
    <input type="password" class="form-control" id="loginpass" name="loginpass" placeholder="Enter your password "required>
  </div>
 
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
       <div class="modal-footer">
      </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
  </body>
</html>

Django 3 Blog: Login & Logout Endpoints | Python Django Tutorials In Hindi #88

In the previous tutorial, we improved the signup functionality of the iCoder blog. After sign up feature, the next most important thing is to create a login and logout functionality. So, let's see how we can create a login and logout feature on our iCoder blog. We will start by defining URLs patterns. So, open the urls.py of the home app and include the following paths :

    path('login', views.handeLogin, name="handleLogin"),
    path('logout', views.handelLogout, name="handleLogout"),

Now, open the base.html file and make the changes as directed below :

  1. Set the id and name of the username input field as id="loginusername" and name="loginusername"
  2. Similarly, set the id and name of the password input field as id="loginpassword" and name="loginpassword."

Now, it's time to define functions for logging in and out. But before that, open the views.py file of the home app and type the below code to import the Django's login and logout feature:

from django.contrib.auth  import authenticate,  login, logout

After importing the above functions, type the below code :

def handeLogin(request):
    if request.method=="POST":
        # Get the post parameters
        loginusername=request.POST['loginusername']
        loginpassword=request.POST['loginpassword']

        user=authenticate(username= loginusername, password= loginpassword)
        if user is not None:
            login(request, user)
            messages.success(request, "Successfully Logged In")
            return redirect("home")
        else:
            messages.error(request, "Invalid credentials! Please try again")
            return redirect("home")

    return HttpResponse("404- Not found")

Let me explain the above code to you. First of all, we saved the username and password in loginusername and loginpassword variable password, respectively. After this, we've used the authenticate() function of Django; authenticate() function takes two keyword arguments :

  1. username
  2. password

If the username and password are correct, it returns a user object for the given username otherwise, it returns None. After this, we've used an if loop to check whether the user is None or not. If the user is None, it means the provided credentials are incorrect, and we will display an error message. If the user is not None, then we are using the login() function of Django. The login() function also takes two arguments:

  1. request: A HttpResponse object.
  2. user: User object returned by the authenticate() function.

As soon as the login function executes, Django's session framework saves the user's id in the session. After successfully logging in, we will redirect the user to the home page of the iCoder blog. Now, we will define a function to log out the user. Type the below code in the views.py file:

def handelLogout(request):
    logout(request)
    messages.success(request, "Successfully logged out")
    return redirect('home')

To logout the user, we're using the logout function of Django.  It takes an HttpRequest and returns None. As soon as the logout() is called, it immediately ends the session of the currently logged in user and clears all the session data to prevent another user's access over the data of the previously logged in user. This is all for this tutorial, and in the next tutorial, we will create templates for the login and logout function.

Code home/views.py as described/written in the video:

from django.shortcuts import render, HttpResponse, redirect
from home.models import Contact
from django.contrib import messages 
from django.contrib.auth.models import User 
from django.contrib.auth  import authenticate,  login, logout
from blog.models import Post

def home(request): 
    return render(request, "home/home.html")

def contact(request):
    if request.method=="POST":
        name=request.POST['name']
        email=request.POST['email']
        phone=request.POST['phone']
        content =request.POST['content']
        if len(name)<2 or len(email)<3 or len(phone)<10 or len(content)<4:
            messages.error(request, "Please fill the form correctly")
        else:
            contact=Contact(name=name, email=email, phone=phone, content=content)
            contact.save()
            messages.success(request, "Your message has been successfully sent")
    return render(request, "home/contact.html")

def search(request):
    query=request.GET['query']
    if len(query)>78:
        allPosts=Post.objects.none()
    else:
        allPostsTitle= Post.objects.filter(title__icontains=query)
        allPostsAuthor= Post.objects.filter(author__icontains=query)
        allPostsContent =Post.objects.filter(content__icontains=query)
        allPosts=  allPostsTitle.union(allPostsContent, allPostsAuthor)
    if allPosts.count()==0:
        messages.warning(request, "No search results found. Please refine your query.")
    params={'allPosts': allPosts, 'query': query}
    return render(request, 'home/search.html', params)

def handleSignUp(request):
    if request.method=="POST":
        # Get the post parameters
        username=request.POST['username']
        email=request.POST['email']
        fname=request.POST['fname']
        lname=request.POST['lname']
        pass1=request.POST['pass1']
        pass2=request.POST['pass2']

        # check for errorneous input
        if len(username)<10:
            messages.error(request, " Your user name must be under 10 characters")
            return redirect('home')

        if not username.isalnum():
            messages.error(request, " User name should only contain letters and numbers")
            return redirect('home')
        if (pass1!= pass2):
             messages.error(request, " Passwords do not match")
             return redirect('home')
        
        # Create the user
        myuser = User.objects.create_user(username, email, pass1)
        myuser.first_name= fname
        myuser.last_name= lname
        myuser.save()
        messages.success(request, " Your iCoder has been successfully created")
        return redirect('home')

    else:
        return HttpResponse("404 - Not found")


def handeLogin(request):
    if request.method=="POST":
        # Get the post parameters
        loginusername=request.POST['loginusername']
        loginpassword=request.POST['loginpassword']

        user=authenticate(username= loginusername, password= loginpassword)
        if user is not None:
            login(request, user)
            messages.success(request, "Successfully Logged In")
            return redirect("home")
        else:
            messages.error(request, "Invalid credentials! Please try again")
            return redirect("home")

    return HttpResponse("404- Not found")
   

    return HttpResponse("login")

def handelLogout(request):
    logout(request)
    messages.success(request, "Successfully logged out")
    return redirect('home')


def about(request): 
    return render(request, "home/about.html")

Code home/urls.py as described/written in the video:

from django.contrib import admin
from django.urls import path, include
from home import views

urlpatterns = [
    path('', views.home, name="home"),
    path('contact', views.contact, name="contact"),
    path('about', views.about, name="about"),
    path('search', views.search, name="search"),
    path('search', views.search, name="search"),
    path('signup', views.handleSignUp, name="handleSignUp"),
    path('login', views.handeLogin, name="handleLogin"),
    path('logout', views.handelLogout, name="handleLogout"),
]

Code base.html as described/written in the video:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <title>{% block title %}   {% endblock title %}</title>
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="/">iCoder</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item {% block homeactive %}  {% endblock homeactive %}">
              <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item {% block aboutactive %}  {% endblock aboutactive %}" >
              <a class="nav-link" href="/about">About</a>
            </li>
            <li class="nav-item {% block contactactive %}  {% endblock contactactive %} ">
              <a class="nav-link" href="/contact">Contact</a>
            </li>
            <li class="nav-item {% block blogactive %}  {% endblock blogactive %} ">
              <a class="nav-link" href="/blog">Blog</a>
            </li>
            
          </ul>
          <form method="get" action="/search"class="form-inline my-2 my-lg-0 mx-3">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="query" id="query">
            <button class="btn btn-outline-success my-2 my-sm-0 " type="submit">Search</button>
            <a href="/admin" role="button" target="_blank" class="btn btn-outline-success m-2 my-sm-0"> Admin Panel </a>
          </form>

               <!-- Button to  trigger SignUp modal -->

  <!-- Button to  trigger Login modal -->
<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#loginModal">
Login
</button>

<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#signupModal">
SignUp
</button>


        </div>
      </nav>
      {% for message in messages  %}            
      <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <strong>Message : </strong> {{ message }}
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
      {% endfor %}    



 

<!-- SignUp Modal -->
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="signupModalTitle">SignUp Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action= "/signup" method='post'>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="username" name="username" placeholder="Choose a unique username" required>
  </div>
  <div class="form-group">
    <label for="fname">First Name</label>
    <input type="text" class="form-control" id="fname" name="fname" placeholder="Enter Your First Name" required>
  </div>
  <div class="form-group">
    <label for="lname">Last Name</label>
    <input type="text" class="form-control" id="lname" name="lname" placeholder="Enter Your Last Name" required>
  </div>
  <div class="form-group">
    <label for="email">Email address</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="name@example.com" required>
  </div>
  <div class="form-group">
    <label for="pass1">Choose a password</label>
    <input type="password" class="form-control" id="pass1" name="pass1" placeholder="Choose Your Password" required>
  </div>
  <div class="form-group">
    <label for="pass2">Confirm Password</label>
    <input type="password" class="form-control" id="pass2" name="pass2" placeholder="Enter your password again" required>
  </div>
 

        {% csrf_token %}
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
      <div class="modal-footer">
      </div>
    </div>
  </div>
</div>






      {% block body %}  {% endblock body %}

<!-- Login Modal -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="loginModalTitle">Login Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action="/login" method="POST"> {% csrf_token %}
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="loginusername" name="loginusername" placeholder="Enter your username "required>
  </div>
  <div class="form-group">
    <label for="pass">Enter your password </label>
    <input type="password" class="form-control" id="loginpassword" name="loginpassword" placeholder="Enter your password "required>
  </div>
 
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
       <div class="modal-footer">
      </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
  </body>
</html>

Django 3 Blog: Creating Django template for Login & Logout | Python Django Tutorials In Hindi #89

In the last tutorial, we saw how we could create login and logout functionality by using Django's inbuilt functions. Now, we need to create a Django template to display a welcome message to the user on logging in. To do so, open the base.html file and type the below code :

{% if user.is_authenticated %}
<ul class="navbar-nav mr-2">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href='#' id="navbarDropdown" role="button" data-toggle="dropdown"> Welcome {{request.user}}</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="/logout">Logout</a>

        </div>
      </li>
      </ul>
      </div>
{% else %}
  <!-- Button to  trigger Login modal -->
<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#loginModal">
Login
</button>

<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#signupModal">
SignUp
</button>
{% endif %}

In the above code, we've used an if block to check if the user is already logged in or not. If the user is already logged in, then we will display a welcome message otherwise, the else loop will execute and the login and signup button will be displayed. Now, let's check if everything is working correctly or not. Restart the development server, and you will see the following screen :

In the above image, you can see that login and signup buttons are displayed as I've not logged in yet. Now, I will try to login after creating a new user.

Input :

Output:

In the above image, you can see that a success message is displayed as the account has been created successfully. Now, let's try to login with the same username.

Input :

Output:

You can clearly see that a welcome message is displayed and I am logged in successfully. I hope all the concepts of authentication and authorization are clear to you. You can ask your doubts in the QnA section. 

 

Code home/views.py as described/written in the video:

from django.shortcuts import render, HttpResponse, redirect
from home.models import Contact
from django.contrib import messages 
from django.contrib.auth.models import User 
from django.contrib.auth  import authenticate,  login, logout
from blog.models import Post

def home(request): 
    return render(request, "home/home.html")

def contact(request):
    if request.method=="POST":
        name=request.POST['name']
        email=request.POST['email']
        phone=request.POST['phone']
        content =request.POST['content']
        if len(name)<2 or len(email)<3 or len(phone)<10 or len(content)<4:
            messages.error(request, "Please fill the form correctly")
        else:
            contact=Contact(name=name, email=email, phone=phone, content=content)
            contact.save()
            messages.success(request, "Your message has been successfully sent")
    return render(request, "home/contact.html")

def search(request):
    query=request.GET['query']
    if len(query)>78:
        allPosts=Post.objects.none()
    else:
        allPostsTitle= Post.objects.filter(title__icontains=query)
        allPostsAuthor= Post.objects.filter(author__icontains=query)
        allPostsContent =Post.objects.filter(content__icontains=query)
        allPosts=  allPostsTitle.union(allPostsContent, allPostsAuthor)
    if allPosts.count()==0:
        messages.warning(request, "No search results found. Please refine your query.")
    params={'allPosts': allPosts, 'query': query}
    return render(request, 'home/search.html', params)

def handleSignUp(request):
    if request.method=="POST":
        # Get the post parameters
        username=request.POST['username']
        email=request.POST['email']
        fname=request.POST['fname']
        lname=request.POST['lname']
        pass1=request.POST['pass1']
        pass2=request.POST['pass2']

        # check for errorneous input
        if len(username)<10:
            messages.error(request, " Your user name must be under 10 characters")
            return redirect('home')

        if not username.isalnum():
            messages.error(request, " User name should only contain letters and numbers")
            return redirect('home')
        if (pass1!= pass2):
             messages.error(request, " Passwords do not match")
             return redirect('home')
        
        # Create the user
        myuser = User.objects.create_user(username, email, pass1)
        myuser.first_name= fname
        myuser.last_name= lname
        myuser.save()
        messages.success(request, " Your iCoder has been successfully created")
        return redirect('home')

    else:
        return HttpResponse("404 - Not found")


def handeLogin(request):
    if request.method=="POST":
        # Get the post parameters
        loginusername=request.POST['loginusername']
        loginpassword=request.POST['loginpassword']

        user=authenticate(username= loginusername, password= loginpassword)
        if user is not None:
            login(request, user)
            messages.success(request, "Successfully Logged In")
            return redirect("home")
        else:
            messages.error(request, "Invalid credentials! Please try again")
            return redirect("home")

    return HttpResponse("404- Not found")
   

    return HttpResponse("login")

def handelLogout(request):
    logout(request)
    messages.success(request, "Successfully logged out")
    return redirect('home')


def about(request): 
    return render(request, "home/about.html")

Code home/urls.py as described/written in the video:

from django.contrib import admin
from django.urls import path, include
from home import views

urlpatterns = [
    path('', views.home, name="home"),
    path('contact', views.contact, name="contact"),
    path('about', views.about, name="about"),
    path('search', views.search, name="search"),
    path('search', views.search, name="search"),
    path('signup', views.handleSignUp, name="handleSignUp"),
    path('login', views.handeLogin, name="handleLogin"),
    path('logout', views.handelLogout, name="handleLogout"),
]

Code base.html as described/written in the video:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <title>{% block title %}   {% endblock title %}</title>
  </head>
  <body>

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <a class="navbar-brand" href="/">iCoder</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
      
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item {% block homeactive %}  {% endblock homeactive %}">
              <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item {% block aboutactive %}  {% endblock aboutactive %}" >
              <a class="nav-link" href="/about">About</a>
            </li>
            <li class="nav-item {% block contactactive %}  {% endblock contactactive %} ">
              <a class="nav-link" href="/contact">Contact</a>
            </li>
            <li class="nav-item {% block blogactive %}  {% endblock blogactive %} ">
              <a class="nav-link" href="/blog">Blog</a>
            </li>
            
          </ul>
          <div class="ml-auto form-inline ">
          <form method="get" action="/search"class="my-2 my-lg-0 mx-3">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="query" id="query">
            <button class="btn btn-outline-success my-2 my-sm-0 " type="submit">Search</button>
            <a href="/admin" role="button" target="_blank" class="btn btn-outline-success m-2 my-sm-0"> Admin Panel </a>
          </form>

     

{% if user.is_authenticated %}
<ul class="navbar-nav mr-2">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href='#' id="navbarDropdown" role="button" data-toggle="dropdown"> Welcome {{request.user}}</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="/logout">Logout</a>

        </div>
      </li>
      </ul>
      </div>
{% else %}
  <!-- Button to  trigger Login modal -->
<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#loginModal">
Login
</button>

<button type="button" class="btn btn-success mr-2" data-toggle="modal" data-target="#signupModal">
SignUp
</button>
{% endif %}


        </div>
      </nav>
      {% for message in messages  %}            
      <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
            <strong>Message : </strong> {{ message }}
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
      {% endfor %}    



 

<!-- SignUp Modal -->
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="signupModalTitle">SignUp Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action= "/signup" method='post'>
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="username" name="username" placeholder="Choose a unique username" required>
  </div>
  <div class="form-group">
    <label for="fname">First Name</label>
    <input type="text" class="form-control" id="fname" name="fname" placeholder="Enter Your First Name" required>
  </div>
  <div class="form-group">
    <label for="lname">Last Name</label>
    <input type="text" class="form-control" id="lname" name="lname" placeholder="Enter Your Last Name" required>
  </div>
  <div class="form-group">
    <label for="email">Email address</label>
    <input type="email" class="form-control" id="email" name="email" placeholder="name@example.com" required>
  </div>
  <div class="form-group">
    <label for="pass1">Choose a password</label>
    <input type="password" class="form-control" id="pass1" name="pass1" placeholder="Choose Your Password" required>
  </div>
  <div class="form-group">
    <label for="pass2">Confirm Password</label>
    <input type="password" class="form-control" id="pass2" name="pass2" placeholder="Enter your password again" required>
  </div>
 

        {% csrf_token %}
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
      <div class="modal-footer">
      </div>
    </div>
  </div>
</div>






      {% block body %}  {% endblock body %}

<!-- Login Modal -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="loginModalTitle">Login Here</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <form action="/login" method="POST"> {% csrf_token %}
  <div class="form-group">
    <label for="username">Username</label>
    <input type="text" class="form-control" id="loginusername" name="loginusername" placeholder="Enter your username "required>
  </div>
  <div class="form-group">
    <label for="pass">Enter your password </label>
    <input type="password" class="form-control" id="loginpassword" name="loginpassword" placeholder="Enter your password "required>
  </div>
 
        <button type="submit" class="btn btn-primary">Submit</button>
</form>
      </div>
       <div class="modal-footer">
      </div>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
  </body>
</html>

 

Comments

Popular posts from this blog

Connect and Configure MongoDB in Django Project

  Django, a high-level Python web framework, is well-known for its robustness and versatility. While Django natively supports popular databases like PostgreSQL and MySQL, you may want to integrate a NoSQL database like MongoDB for specific use cases. MongoDB’s flexibility and scalability make it an excellent choice for handling unstructured data. In this blog, we will walk you through the process of connecting MongoDB to a Django project, enabling you to harness the power of NoSQL in your web applications. Prerequisites: Before we begin, ensure you have the following prerequisites in place: Django installed on your system. MongoDB database server installed and running. Basic familiarity with Django project structure and database concepts. Virtual Environment, this is optional but recommended. You check our blog  here . Note:  For this tutorial, we are using our basic  skeleton project  for Django. You can also download the project from  here . Step 1: Insta...

How to host Django Application in AWS using gunicorn & nginx in Production

in this post, we will see how to use    nginx  with    gunicorn  to serve    django     applications  in production.  Django is a very powerful web framework and ships with a server which is able to facilitate development. This development server is not scalable and is not suited for production. Hence we need to configure gunicorn to get better scalability and nginx can be used as a reverse proxy and as a web server to serve static files. Let's get started  Step 1 - Installing python and nginx Let's update the server's package index using the command below: sudo apt update Copy sudo apt install python3-pip python3-dev nginx Copy This will install python, pip and nginx server Step 2 - Creating a python virtual environment  sudo pip3 install virtualenv Copy This will install a virtual environment package in python. Let's create a project directory to host our Django application and create a virtual environment inside th...

Mongodb-CheatSheet

  All MongoDb commands you will ever need (MongoDb Cheatsheet) In this post, we will see a comprehensive list of all the    MongoDB  commands you will ever need as a MongoDB beginner. This list covers almost all the most used commands in MongoDB. I will assume that you are working inside a collection named 'comments' on a MongoDB    database  of your choice 1. Database Commands View all databases show dbs Copy Create a new or switch databases  use dbName Copy View current Database db Copy Delete Database  db . dropDatabase ( ) Copy 2. Collection Commands Show Collections show collections Copy Create a collection named 'comments' db . createCollection ( 'comments' ) Copy Drop a collection named 'comments' db . comments . drop ( ) Copy 3. Row(Document) Commands Show all Rows in a Collection  db . comments . find ( ) Copy Show all Rows in a Collection (Prettified) db . comments . find ( ) . pretty ( ) Copy Find the first row matching the ob...