FriendBook - The Social Media
Tags: django, python
Published: 2021-01-14 10:15:02

Do u use any *Social Networking Site* like [Facebook](https://m.facebook.com/madhubankhatri.98) or [Instagram](https://instagram.com/mr.khatri_21)? Yes... Than try my *FriendBook*. 
Here u can get experience of FriendBook and it is easy to use.

Here is Demo Video:-
{% youtube kMqh3_UngA0 %}

Functionallity of *FriendBook*:-
* Easy to use
* Create, Update and Delete Posts
* Like and Comment the posts
* Follow or Unfollow other users
* Find your friends on FriendBook


#Source Code

### models.py
```python
from django.db import models

# Create your models here.
class User(models.Model):
	full_name = models.CharField(max_length=100)
	user_name = models.CharField(max_length=100)
	email = models.EmailField()
	password = models.CharField(max_length=50)
	bio = models.TextField(default='')
	profile_pic = models.ImageField(upload_to='profile_pic/', default='profile_pic/default.jpg')
	date_joined = models.DateField(auto_now_add=True)

	def __str__(self):
		return self.full_name



class Follower(models.Model):
	user = models.OneToOneField(User, on_delete=models.CASCADE)
	another_user = models.ManyToManyField(User, related_name='another_user')

	def __str__(self):
		return self.user.user_name



class Post(models.Model):
	user = models.ForeignKey(User, on_delete = models.CASCADE)
	img = models.ImageField(upload_to='post_images/')
	desc = models.TextField()
	likes = models.ManyToManyField(User, related_name='likes')
	pub_date = models.DateTimeField(auto_now_add=True)

	class Meta:
		ordering = ['-pub_date']

	def __str__(self):
		return self.img.url



class Comment(models.Model):
	user = models.ForeignKey(User, on_delete=models.CASCADE)
	post = models.ForeignKey(Post, on_delete=models.CASCADE)
	comment = models.CharField(max_length=500)

```

### admin.py
```python
from django.contrib import admin
from .models import User, Post, Comment, Follower
# Register your models here.
@admin.register(User)
class userAdmin(admin.ModelAdmin):
  list_display = ('id', 'full_name', 'user_name', 'email', 'password')

@admin.register(Comment)
class commentAdmin(admin.ModelAdmin):
  list_display = ('id', 'user', 'post', 'comment')


admin.site.register(Post)

admin.site.register(Follower)

```

### urls.py
```python
from django.urls import path
from . import views

urlpatterns = [
	path('', views.index, name='index'),

	path('<str:username>/profile/', views.profile, name='profile'),
	path('upload/', views.upload_post, name='upload_post'),
	path('update_profile/', views.update_profile, name='update_profile'),
	path('add_like/', views.add_like, name='add_like'),
	path('add_comment/', views.add_comment, name='add_comment'),
	path('del_post/', views.del_post, name='delete_post'),

	path('follow_user/', views.follow_user, name='follow_user'),

	path('login/' ,views.user_login, name='user_login'),
	path('logout/' ,views.user_logout, name='user_logout'),


	path('signup/', views.user_signup, name='user_signup'),


	path('search/' ,views.search, name='search_user'),

]
```

### views.py
```python
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from .models import User, Post, Comment, Follower
from django.contrib import messages
from django.urls import reverse_lazy, reverse


# Create your views here.
def index(request):
	if 'user' in request.session:
		session_user_obj = User.objects.get(user_name=request.session['user'])
		check_follower = Follower.objects.get_or_create(user=session_user_obj)[0]
		check_follower.another_user.add(session_user_obj)
		following_users = Follower.objects.filter(another_user=session_user_obj)

		suggest_users = User.objects.all().exclude(user_name=request.session['user'])[:8]
		
		params = {'following_users': following_users, 'user_obj': session_user_obj, 'suggest_users': suggest_users}
		return render(request, 'home.html', params)
	else:
		return render(request, 'welcome.html')



	
def profile(request, username):
	try:
		user_obj = User.objects.get(user_name=username)
	except:
		messages.warning(request, 'User does not exists.')
		return HttpResponseRedirect(reverse('profile', args=[str(request.session['user'])]))
	user_posts = user_obj.post_set.all().order_by('-id')
	
	# session user object
	try:
		session_user_obj = User.objects.get(user_name=request.session['user'])
	except:
		messages.warning(request, 'You have to login first.')
		return redirect('index')

	# check follower
	check_follower = Follower.objects.get_or_create(user=user_obj)[0]

	#count following
	following_user_count = Follower.objects.filter(another_user=user_obj).count()

	is_followed = False
	if session_user_obj in check_follower.another_user.all():
		is_followed = True

	params = {'posts': user_posts, 'user_data':user_obj,'session_obj':session_user_obj, 'is_followed': is_followed, 'followers_count': check_follower.another_user.count(), 'following_count': following_user_count}
	return render(request, 'profile.html', params)



def update_profile(request):
	if request.method == 'POST':
		user_obj = User.objects.get(user_name=request.session['user'])
		try:
			new_img = request.FILES['new_img']
		except:
			new_img = user_obj.profile_pic
		new_email = request.POST['mail']
		new_bio = request.POST['bio']

		
		if new_img:
			user_obj.profile_pic = new_img
		user_obj.email = new_email
		user_obj.bio = new_bio
		user_obj.save()
		
	return HttpResponseRedirect(reverse('profile', args=[str(request.session['user'])]))




def upload_post(request):
	if request.method == 'POST':
		user_obj = User.objects.get(user_name=request.session['user'])
		image_name = request.FILES['file_name']
		desc = request.POST['desc']
		upload_post = Post.objects.create(user=user_obj, img=image_name, desc=desc)
		upload_post.save()
		messages.success(request, 'Post uploaded successfully.')
	return render(request, 'upload.html')


def add_like(request):
	post_id = request.GET['postId']
	user_obj = User.objects.get(user_name=request.session['user'])
	post_obj = Post.objects.get(id=post_id)
	is_liked = False

	if user_obj in post_obj.likes.all():
		post_obj.likes.remove(user_obj)
		is_liked = True
	else:
		post_obj.likes.add(user_obj)
		is_liked = False

	return JsonResponse({'status': 'Ok', 'post_likes': post_obj.likes.count(), 'isLiked': is_liked})




def add_comment(request):
	comment = request.GET['comment']
	post_id = request.GET['post_id']
	
	user_obj = User.objects.get(user_name=request.session['user'])
	post_obj = Post.objects.get(id=post_id)

	add_comment = Comment(user=user_obj, post=post_obj, comment=comment)
	add_comment.save()

	get_comments = Comment.objects.filter(post=post_obj)
	return JsonResponse({'comment': add_comment.comment, 'user': user_obj.full_name, 'comment_count': get_comments.count()})



def follow_user(request):
	userId = request.GET['userId']
	# another user
	user_obj = User.objects.get(id=userId)
	# session user
	session_user_obj = User.objects.get(user_name=request.session['user'])
	# Follower obj
	check_follower = Follower.objects.get_or_create(user=user_obj)[0] #It is <Follower:user_obj>
	
	is_followed = False
	if session_user_obj in check_follower.another_user.all():
		is_followed = True
		check_follower.another_user.remove(session_user_obj)
	else:
		is_followed = False
		check_follower.another_user.add(session_user_obj)
	print('user id: ', userId)
	return JsonResponse({'status': 'Ok', 'isFollowed': is_followed, 'followers_count': check_follower.another_user.count()})



def user_login(request):
	if request.method == 'POST':
		userName = request.POST['uname']
		userPwd = request.POST['pwd']

		check_user = User.objects.filter(user_name=userName, password=userPwd)
		if check_user:
			request.session['user'] = userName
			messages.success(request, f'You have loggedin as {userName}!')
			return redirect('index')
		else:
			messages.warning(request, 'Invalid Username or Password.')
			return redirect('index')
	return redirect('index')



def user_logout(request):
	del request.session['user']
	return redirect('index')



def user_signup(request):
	if request.method == 'POST':
		fullName = request.POST['fname']
		userName = request.POST['uname']
		mail = request.POST['mail']
		userPwd = request.POST['pwd']
		
		new_user = User(full_name=fullName, user_name=userName, email=mail, password=userPwd)
		new_user.save()
		messages.success(request, 'Account has been created successfully.')
	return redirect('index')




def search(request):
	if request.method == 'GET':
		user_query = request.GET['query']

		search_users_uname = User.objects.filter(user_name__icontains=user_query)
		search_users_fname = User.objects.filter(full_name__icontains=user_query)

		search_results = search_users_uname.union(search_users_fname)
		
		params = {'results': search_results}
		return render(request, 'search.html', params)




def del_post(request):
	if request.method == 'GET':
		post_id = request.GET['postId']
		post_obj = Post.objects.get(id=post_id)
		post_obj.delete()

		return JsonResponse({'status': 'Ok', 'id': post_id})
	else:
		return JsonResponse({'status': 'not Ok'})
```
## Templates Work
### base.html
```html
<!doctype html>
<html lang="en">
<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  {% load static %}
  <!-- Bootstrap CSS -->
  <link rel="stylesheet" type="text/css" href="{% static 'css/css.css' %}">
  <link rel="stylesheet" type="text/css" href="{% static 'css/font_awsome.css' %}">

  <!--Add Jquery-->
  <script type="text/javascript" src="{% static 'js/my_jquery.js' %}"></script>

  <title>{% block title %}{% endblock %}</title>
</head>
<body>
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
      <a class="navbar-brand" href="#">Friend<span style="color: red;">Book</span></a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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 me-auto mb-2 mb-lg-0">
          <li class="nav-item">
            <a class="nav-link active" aria-current="page" href="{% url 'index' %}">Home</a>
          </li>
        </ul>
        <form class="d-flex" action="{% url 'search_user' %}" method="get">
          <input class="form-control me-2" type="search" name="query" placeholder="Search User" aria-label="Search">
          <button class="btn btn-outline-success" type="submit">Search</button>
        </form>

        {% if request.session.user %}
        <div class="btn-group mx-4">
          <button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" data-bs-display="static" aria-expanded="false">
            @{{request.session.user}}
          </button>
          <ul class="dropdown-menu dropdown-menu-end dropdown-menu-lg-start">
            <li><a href="{% url 'profile' request.session.user %}" class="dropdown-item">Profile</a></li>
            <li><a href="{% url 'upload_post' %}" class="dropdown-item">Upload Post</a></li>
            <li><hr class="dropdown-divider"></li>
            <li><a href="{% url 'user_logout' %}" class="dropdown-item text-danger">Logout</a></li>
          </ul>
        </div>
        {% endif %}

      </div>
    </div>
  </nav>

  {% if messages %}
    {% for message in messages %}
    <div class="alert alert-{{message.tags}} alert-dismissible fade show" role="alert">
      <strong>{{message}}</strong>
      <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
    </div>
    {% endfor %}
  {% endif %}

  {% block body %}
  {% endblock %}


  <!-- Option 1: Bootstrap Bundle with Popper -->
  <script type="text/javascript" src="{% static 'js/js.js' %}"></script>


</body>
</html>
```


### welcome.html
```html
{% extends 'base.html' %}
{% load static %}
{% block title %}
Welcome to FriendBook	
{% endblock %}

{% block body %}

<div class="container-fluid text-center">
	<div class="card bg-dark text-white">
		<img src="{% static 'img1.jpg' %}" class="card-img" alt="..." style="height: 400px; opacity: 0.5;">
		<div class="card-img-overlay" style="margin-top: 100px;">
			<h1 class="card-title" style="text-shadow: 2px 5px black; font-size: 50px;">Welcome to <span style="color: dodgerblue;">FriendBook</span></h1>
			<p class="card-text" style="font-size: 20px; text-shadow: 2px 2px black;">Find your Family, Relatives, Friends and Make your Connection here</p>

		</div>
	</div>
</div>


<div class="container my-4">
	<div class="row">
		<div class="col-5 alert alert-success mx-2 my-3">
			<h4>Login</h4>
			<form action="{% url 'user_login' %}" method="post">
				{% csrf_token %}
				<div class="mb-3">
					<label for="exampleFormControlInput1" class="form-label">Username</label>
					<input type="text" name="uname" class="form-control" id="exampleFormControlInput" required>
				</div>
				<div class="mb-3">
					<label for="exampleFormControlPassword" class="form-label">Password</label>
					<input type="password" name="pwd" class="form-control" name="" id="exampleFormControlPassword" required>
				</div>
				<input type="submit" name="" value="Login" class="btn btn-outline-success">
			</form>
		</div>

		<div class="col-6 alert alert-info my-3">
			<h4>Signup</h4>
			<form action="{% url 'user_signup' %}" method="post">
				{% csrf_token %}
				<div class="mb-3">
					<label for="exampleFormControlInput1" class="form-label">Full Name</label>
					<input type="text" class="form-control" name="fname" id="exampleFormControlInput" required>
				</div>
				<div class="mb-3">
					<label for="exampleFormControlInput1" class="form-label">Username</label>
					<input type="text" class="form-control" name="uname" id="exampleFormControlInput" required>
				</div>
				<div class="mb-3">
					<label for="exampleFormControlEmail" class="form-label">Email</label>
					<input type="email" class="form-control" name="mail" id="exampleFormControlEmail" required>
				</div>
				<div class="mb-3">
					<label for="exampleFormControlPassword" class="form-label">Password</label>
					<input type="password" class="form-control" name="pwd" name="" id="exampleFormControlPassword" required>
				</div>
				<input type="submit" value="Signup" class="btn btn-primary">
			</form>
		</div>
	</div>
</div>

{% endblock %}
```


### index.html
```html
{% extends 'base.html' %}
{% load static %}
{% block body %}
<div class="container my-4">
	<div class="row">
		
		
		<div class="col-7 border">
			{% for user in following_users %}
			{% for post in user.user.post_set.all %}
			<div class="card my-2 w-100">
				<h5 class="card-header my-2"><a href="{% url 'profile' user.user.user_name %}" style="text-decoration: none;">{{user.user.full_name}}</a>
					<span class="text-muted" style="float: right; font-size: 15px;">{{post.pub_date}}</span>
				</h5>

				<div class="container">
					<img src="{% static post.img.url %}" class="img-thumbnail w-100" style="width: 30rem; height: 30rem;">
				</div>
				<div class="card-body">
					<p class="card-text">{{post.desc}}</p>
					<button class="btn btn-danger like_btn" id="{{post.id}}"><span id="likes_count{{post.id}}">{{post.likes.count}}</span> <span id="sign{{post.id}}">
						{% if user_obj in post.likes.all %}
						<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
							{% else %}
							<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16"><path d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/></svg>
							{% endif %}
						</span></button>
						<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#exampleModal{{post.id}}"><span id="comment_count{{post.id}}">{{post.comment_set.count}}</span> Comment</button>

						<!--Comment Modal-->   
						<div class="modal fade" id="exampleModal{{post.id}}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
							<div class="modal-dialog modal-dialog-scrollable">
								<div class="modal-content">
									<div class="modal-header">
										<h5 class="modal-title" id="exampleModalLabel">Public Comments</h5>
										<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
									</div>
									<div class="modal-body">
										<div class="mb-2">
											<form id="comment_form{{post.id}}">
												<input type="text" class="form-control" placeholder="Add Comment..." id="comment_box{{post.id}}">
											</form>
										</div>
										<div class="mb-3">
											<div class="container" id="comment_container{{post.id}}">
												{% for comment in post.comment_set.all %}

												<b>
													{{comment.user}}
												</b>
												<p>
													{{comment.comment}}
												</p>

												{% endfor %}
											</div>
										</div>
									</div>
									<div class="modal-footer">
										<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
										<button type="button" class="btn btn-primary comment_btn" id="{{post.id}}">Add Comment</button>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				{% endfor %}
				{% endfor %}

			</div>

			<div class="col w-100">
				<h2>Suggetions</h2>
				<hr>
				<div class="container">
					{% for user in suggest_users %}
					<div class="card">
						<div class="row">
							<div class="col-6">
								<img src="{% static user.profile_pic.url %}" class="w-50">
							</div>

							<div class="col-6">
								<h5 class="text-center" style="display: inline;"><a class="text-dark" href="{% url 'profile' user.user_name %}" style="text-decoration: none;">{{user.user_name}}</a></h5>							
							</div>
						</div>
					</div>
					{% endfor %}
				</div>
			</div>
		</div>
	</div>

	<script type="text/javascript">
	var like_btn = $('.like_btn');
	like_btn.on('click', function(event){
		event.preventDefault();
		var t = this;
		// alert(t.getAttribute('id'));
		$.ajax({
			type: 'GET',
			url: '{% url "add_like" %}',
			data: {postId: t.getAttribute('id')},
			dataType: 'json',
			success: function(data){
				$('#likes_count'+t.getAttribute('id')).text(data.post_likes);
				var sign = $('#sign'+t.getAttribute('id'));				
				if(data.isLiked)
				{
					sign.html('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16"><path d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/></svg>');
				}
				else
				{
					sign.html('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>');	
				}
			}
		});
	});

	</script>


	<script type="text/javascript">
	// Add Comments
	var comment_btn = $('.comment_btn');
	comment_btn.on('click', function(event){
		event.preventDefault();
		var t = this;
		var comment_val = $('#comment_box'+t.getAttribute('id')).val();
		var commentContainer = $('#comment_container'+t.getAttribute('id'));
		var commentCount = $('#comment_count'+t.getAttribute('id'));

		$.ajax({
			type: 'GET',
			url: '{% url "add_comment" %}',
			data: {comment: comment_val, post_id: t.getAttribute('id')},
			dataType: 'json',
			success: function(data){

				var comment_user = '<b>'+data.user+'</b>';
				var comment_para = '<p>'+data.comment+'</p>';
				commentContainer.prepend(comment_para);
				commentContainer.prepend(comment_user);

				commentCount.text(data.comment_count);

				$('#comment_form'+t.getAttribute('id')).trigger('reset');

			}
		});
	});
	</script>

	{% endblock %}
```

### profile.html
```html
{% extends 'base.html' %}

{% load static %}

{% block title %}Profile{% endblock %}


{% block body %}
<div class="container-fluid my-4">
	<div class="row">
		<div class="col-4 mx-2 bg-light text-dark">
			<div class="row">
				<div class="col">
					<div class="container my-3 text-center">
						{% if user_data.profile_pic %}
						<img src="{% static user_data.profile_pic.url %}" class="w-25" style="float: left;">
						{% endif %}
						<h3 class="text-center">{{user_data.full_name}}</h3>
						<b class="mx-4 text-center"><span style="text-decoration: none;"><span id="follower_count">{{followers_count}}</span> Followers</span></b>
						&nbsp &nbsp &nbsp
						<b class="text-center"><span href="" style="text-decoration: none;">{{following_count}} Following</span></b>
						<br>
						{% if user_data.user_name != request.session.user %}					
						<button class="btn btn-outline-primary" id="follow_btn">
							{% if is_followed %}
								Unfollow
							{% else %}
								Follow
							{% endif %}
						</button>
						{% endif %}
						        
					</div>
				</div>
			</div>
			<div class="row">
				<div class="col">
					<b class="mx-4">Bio: </b>
					<pre><p class="mx-4">{{user_data.bio}}</p></pre>
				</div>
			</div>
			<hr>
			<div class="container-fluid">
				<span class="text-muted">Email: </span>{{user_data.email}}
				<br>
				<span class="text-muted">Date Joined: </span>{{user_data.date_joined}}
				<br>
			</div>
			<hr>

			{% if user_data.user_name == request.session.user %}
			<button class="btn btn-primary w-100" data-bs-toggle="modal" data-bs-target="#editModal">Edit Profile</button>
			{% endif %}
		</div>


		<!--Edit Profile Modal-->   
		<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
			<div class="modal-dialog modal-dialog-scrollable">
				<div class="modal-content">
					<div class="modal-header">
						<h5 class="modal-title" id="exampleModalLabel">Edit Profile</h5>
						<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
					</div>
					<div class="modal-body">
						<form action="{% url 'update_profile' %}" method="post" enctype="multipart/form-data">
							{% csrf_token %}
							<div class="mb-2">
								<div class="row">
									<div class="col-7">
										<label for="imgSection" class="form-label"><b>Choose Image</b></label>
										<input type="file" name="new_img" class="form-control" id="imgSection">
									</div>
									<div class="col">
										<h6>Current Image</h6>
										<img src="{% static user_data.profile_pic.url %}" class="w-50">
									</div>
								</div>
							</div>
							<div class="mb-2">
								<label for="emailSection" class="form-label"><b>Email</b></label>
								<input type="email" name="mail" class="form-control" id="emailSection" value="{{user_data.email}}">
							</div>
							<div class="mb-2">
								<label for="bioSection" class="form-label"><b>Bio (<span id="bio_len">0</span>/150)</b></label>
								<textarea class="form-control" name="bio" id="bio">{{user_data.bio}}</textarea>
							</div>
							<div class="modal-footer">
								<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
								<button type="submit" class="btn btn-primary" id="update_btn">Update</button>
							</div>
						</form>
					</div>

				</div>
			</div>
		</div>


		<div class="col-7 mx-2">
			<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
				<li class="nav-item" role="presentation">
					<a class="nav-link active" id="pills-home-tab" data-bs-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true">List View</a>
				</li>
				<li class="nav-item" role="presentation">
					<a class="nav-link" id="pills-profile-tab" data-bs-toggle="pill" href="#pills-profile" role="tab" aria-controls="pills-profile" aria-selected="false">Grid View</a>
				</li>
			</ul>

			<hr>
			<div class="tab-content" id="pills-tabContent">
				<!--List View-->
				<div class="tab-pane fade show active" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab">
					{% if posts %}
					{% for post in posts %}
					<div class="card border-success bg-light text-dark" id="div{{post.id}}" style="width: 31rem;">
						<img src="{% static post.img.url %}" class="card-img-top" alt="..." style="">
						<div class="card-body">
							<p class="card-text">{{post.desc}}</p>
							<button class="btn btn-primary like_btn" id="{{post.id}}"><span id="list_likes_count{{post.id}}">{{post.likes.count}}</span> <span id="sign{{post.id}}">
								{% if session_obj in post.likes.all %}
									<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
								{% else %}
									<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16"><path d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/></svg>
								{% endif %}

								</span></button>
								<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#exampleModal{{post.id}}"><span id="comment_count{{post.id}}">{{post.comment_set.count}}</span> Comment</button>

								{% if user_data.user_name == request.session.user %}
									<button class="btn btn-danger del_btn" id="delete{{post.id}}" style="float: right;">Delete</button>
								{% endif %}
								<br>
								<span class="text-muted">{{post.pub_date}}</span>
							</div>
						</div>
						<hr>
						<!--Comment Modal-->   
						<div class="modal fade" id="exampleModal{{post.id}}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
							<div class="modal-dialog modal-dialog-scrollable">
								<div class="modal-content">
									<div class="modal-header">
										<h5 class="modal-title" id="exampleModalLabel">Public Comments</h5>
										<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
									</div>
									<div class="modal-body">
										<div class="mb-2">
											<form id="comment_form{{post.id}}">
												<input type="text" class="form-control" placeholder="Add Comment..." id="comment_box{{post.id}}">
											</form>
										</div>
										<div class="mb-3">
											<div class="container" id="comment_container{{post.id}}">
												{% for comment in post.comment_set.all %}

												<b>
													{{comment.user}}
												</b>
												<p>
													{{comment.comment}}
												</p>

												{% endfor %}
											</div>
										</div>
									</div>
									<div class="modal-footer">
										<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
										<button type="button" class="btn btn-primary comment_btn" id="{{post.id}}">Add Comment</button>
									</div>
								</div>
							</div>
						</div>
						{% endfor %}
						{% else %}
						<div class="card text-center">
							<h1>No Posts Yet.</h1>							
						</div>
						{% endif %}

					</div>



					<!--Grid View-->
					<div class="tab-pane fade" id="pills-profile" role="tabpanel" aria-labelledby="pills-profile-tab">
						{% if posts %}
						<div class="row row-cols-1 row-cols-md-3 g-4">
							
							{% for post in posts %}
							<div class="col">
								<div class="card" id="card{{post.id}}">
									<img src="{% static post.img.url %}" class="card-img-top" alt="...">
									<div class="card-body">
										<p class="card-text">{{post.desc}}</p>
										<p><b>

											<span id="grid_likes_count{{post.id}}">{{post.likes.count}}</span>
										Likes</b></p>
										<p><b>
											<span id="grid_comments_count{{post.id}}">{{post.comment_set.count}}</span>
										Comments</b></p>
										<span class="text-muted">{{post.pub_date}}</span>
										
									</div>
								</div>
							</div>
							{% endfor %}
						</div>
						{% else %}
						<div class="card text-center">
							<h1>No Posts Yet.</h1>
						</div>
						{% endif %}


					</div>
				</div>


			</div>

		</div>
	</div>

	
	<script type="text/javascript">
	// Limit The Length of User Bio
	var bio = $('#bio');
	bio.on('input', function(){
		var bio_len = $('#bio_len');
		var text_length = bio.val().length;
		if(text_length>150)
		{
			bio_len.text(text_length);
			$('#bio_len').css('color', 'red');
			document.getElementById('update_btn').disabled = true;
			
		}
		else
		{
			bio_len.text(text_length);
			$('#bio_len').css('color', 'black');
			document.getElementById('update_btn').disabled = false;
		}
		
	});
	</script>


	<script type="text/javascript">
	// Add Likes
	var like_btn = $('.like_btn');
	var list_likes_count = $('#likes_count');
	
	like_btn.on('click', function(event){
		event.preventDefault();
		var t = this;
		$.ajax({
			url: '{% url "add_like" %}',
			data: {postId: this.getAttribute('id')},
			dataType: 'json',
			success: function(data){
				$('#list_likes_count'+t.getAttribute('id')).text(data.post_likes);
				$('#grid_likes_count'+t.getAttribute('id')).text(data.post_likes);
				var sign = $('#sign'+t.getAttribute('id'));
				if(data.isLiked)
				{
					sign.html('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16"><path d="M8 2.748l-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/></svg>');
				}
				else
				{
					sign.html('<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>');	
				}

			}
		});
	});
	</script>



	<script type="text/javascript">
	// Add Comments
	var comment_btn = $('.comment_btn');
	comment_btn.on('click', function(event){
		event.preventDefault();
		var t = this;
		var comment_val = $('#comment_box'+t.getAttribute('id')).val();
		var commentContainer = $('#comment_container'+t.getAttribute('id'));
		var commentCount = $('#comment_count'+t.getAttribute('id'));

		$.ajax({
			type: 'GET',
			url: '{% url "add_comment" %}',
			data: {comment: comment_val, post_id: t.getAttribute('id')},
			dataType: 'json',
			success: function(data){

				var comment_user = '<b>'+data.user+'</b>';
				var comment_para = '<p>'+data.comment+'</p>';
				commentContainer.prepend(comment_para);
				commentContainer.prepend(comment_user);

				commentCount.text(data.comment_count);
				$('#grid_comments_count'+t.getAttribute('id')).text(data.comment_count);

				$('#comment_form'+t.getAttribute('id')).trigger('reset');

			}
		});
	});
	</script>


	<script type="text/javascript">
	// Add Follower
	var follow_btn = $('#follow_btn');
	follow_btn.on('click', function(event){
		event.preventDefault();
		var f_count = $('#follower_count');
		$.ajax({
			type: 'GET',
			url: '{% url "follow_user" %}',
			data: {userId: '{{user_data.id}}'},
			dataType: 'json',
			success: function(data){
				if(data.isFollowed)
				{
					follow_btn.text('Follow');
					f_count.text(data.followers_count);
				}
				else
				{
					follow_btn.text('Unfollow');	
					f_count.text(data.followers_count);
				}

			}
		})
	});
	</script>


	<script type="text/javascript">
	//delete post ajax
	var del_btn = $('.del_btn');
	del_btn.on('click', function(e){
		e.preventDefault();
		var a = confirm('Would you like to delete this post?');
		var t = this;
		var post_id = t.getAttribute('id').slice(6);
		if(a)
		{
			$.ajax({
				type: 'GET',
				url: '{% url "delete_post" %}',
				data: {postId: post_id},
				dataType: 'json',
				success: function(data){
					$('div').remove('#div'+data.id);
					$('div').remove('#card'+data.id);
				}
			});
		}
	});
	</script>

	{% endblock %}
```

### upload.html
```html
{% extends 'base.html' %}

{% block title %}Upload{% endblock %}

{% block body %}

<div class="container my-4">
	<div class="row">

		<div class="col">
			<form action="{% url 'upload_post' %}" method="post" enctype="multipart/form-data">
				{% csrf_token %}
				<div class="mb-3">
					<h3>Upload<span style="color: red;">Now</span></h3>
				</div>
				<hr>
				<div class="mb-3">
					<label for="exampleFormControlInput1" class="form-label">Image</label>
					<input type="file" name="file_name" accept="image/*" class="form-control" id="exampleFormControlInput" required>
				</div>
				<div class="mb-3">
					<label for="exampleFormControlPassword" class="form-label">Description</label>
					<textarea name="desc" class="form-control" style="height: 200px;"></textarea>
				</div>
				<input type="submit" name="" value="Upload" class="btn btn-outline-success">
			</form>
		</div>

	</div>
</div>

{% endblock %}
```

### search.html
```html
{% extends 'base.html' %}

{% load static %}


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

{% block body %}
	
	<div class="contaiiner w-50 mx-4 my-4">
		<h1>Search Results: </h1>
		{% if results %}
		{% for result in results %}
			<div class="card my-4 border border-success  text-center">
				<div class="row">
					<div class="col-3 mx-4">
						<img src="{% static result.profile_pic.url %}" class="img-thumbnail mx-4 w-50" style="border-radius: 50%;">
					</div>
					<div class="col-6">
						<h3 class="card-title my-3"><a href="{% url 'profile' result.user_name %}" style="text-decoration: none; float: left;">{{result.user_name}}</a></h3>
					</div>
				</div>
			</div>
		{% endfor %}
		{% else %}
			<div class="container">
				<h3 class="text-center">No Results Found.</h3>
				
			</div>
		{% endif %}
		
	</div>


{% endblock %}
```

Do you like it? 
Send me your feedback because it incourage me to create more amazing content.