Online Video Sharing Website - Django Project
Tags: django, python
Published: 2021-01-06 13:28:52

Hello Developers,
Do you use **Online Video Sharing Website** like YouTube or Vimeo?
And how to create websites like them?  
Here is the example of Online Video Sharing Website:-
{% youtube 7lQPga4rXIY %}

I am providing the source code of this project and give me feedback to this website. In this project ,  I disabled *Deactivate Account* section of this project so write a code for this section and send it to me.

On this website User can:-
* Create Account
* Watch Videos after Login
* Subscribe others
* Like the videos
* Commenting them
* See Dashboard where users can analysis their videos.
* Update their Profiles
* Deactivate Account (Write the Code for this section and send it to me)

You have to create a Django Project using this command.
```
django-admin startproject video_sharing
```

Create an App in this project
```
python manage.py startapp main
```

## settings.py
```python
# Application definition

INSTALLED_APPS = [
    ...
    'main', #add your app here

]

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'main/static')
]



# Media Settings
MEDIA_ROOT = 'D:\\django_projects\\video_sharing\\main\\static\\media'
MEDIA_URL = 'media/'

```

## project/urls.py
```python
from django.contrib import admin
from django.urls import path, include

from django.conf import settings
from django.conf.urls.static import static

admin.site.site_header = "Viral Video Admin Panel"
admin.site.site_title = "Viral Video Admin Portal"
admin.site.index_title = "Welcome to Video Viral!"

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('main.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```
## main/models.py
```python
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class VideoPost(models.Model):
	user = models.ForeignKey(User, on_delete=models.CASCADE)
	title = models.CharField(max_length=100)
	desc = models.TextField()
	video_file = models.FileField(upload_to='videos/')
	thumbnail = models.ImageField(upload_to='videos/thumbnail/', default='none')
	category = models.CharField(max_length=50, default='none')
	pub_date = models.DateField(auto_now_add=True)
	likes = models.ManyToManyField(User, related_name='likes')
	video_views = models.ManyToManyField(User, related_name='video_views')

	def __str__(self):
		return self.title




class UserData(models.Model):
	user = models.OneToOneField(User, on_delete=models.CASCADE)
	about = models.TextField()
	profile_pic = models.ImageField(upload_to='pic/', default='pic/default.jpg')
	subscribers = models.ManyToManyField(User, related_name='subscribers')




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

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

```

## main/admin.py
```python
from django.contrib import admin
from .models import VideoPost, Comment, UserData

# Register your models here.
admin.site.register(VideoPost)
admin.site.register(Comment)
admin.site.register(UserData)
```

Add Models as Tables in Django Database like this,
```
python manage.py makemigrations
python manage.py migrate
```
You have to create a super user to access Database like this,
```
python manage.py createsuperuser
```

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

urlpatterns = [
	path('', views.home, name='home'),
	path('video/<int:video_id>/', views.watch_video, name='watch_video'),
	path('video/add_comment/', views.add_comment, name='add_comment'),
	path('video/add_like/<int:video_id>/', views.add_like, name='add_like'),
	path('<str:session_username>/profile/', views.profile, name='profile'),
	path('<str:session_username>/dashboard/', views.dashboard, name='dashboard'),
	path('add_subscriber/<viewer>/', views.add_sub, name='add_subscriber'),
	path('upload/', views.upload_video, name='upload'),
	path('edit_video/<int:video_id>', views.edit_video, name='edit_video'),
	path('delete_video/', views.delete_video, name='delete_video'),
	path('update_details/', views.update_details, name='update_details'),
	path('signup/', views.signup, name='signup'),
	path('login/', views.user_login, name='login'),
	path('logout/', views.user_logout, name='logout'),

	path('search/', views.search, name='search'),
]
```

## main/views.py
```python
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.urls import reverse_lazy, reverse
from django.contrib.auth.models import User
from .models import VideoPost, Comment, UserData
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist

# Create your views here.
def home(request):
	if not request.user.is_authenticated:
		demo_videos = VideoPost.objects.all().order_by('-id')[:5]
		params = {'videos': demo_videos}
		return render(request, 'welcome.html', params)
	else:
		all_videos = VideoPost.objects.all().order_by('-id')
		params = {'all_videos': all_videos}
		return render(request, 'home.html', params)

def search(request):
	query = request.GET['search_query']
	try:
		user_obj = User.objects.filter(username__icontains=query)
	except:
		 user_obj = User.objects.none()
	params = {'user_obj': user_obj}
	
	return render(request, 'search_page.html', params)

def upload_video(request):
	if request.method == 'POST':
		title = request.POST['title']
		desc = request.POST['desc']
		video_file = request.FILES['fileName']
		thumb_nail = request.FILES['thumbnail_img']
		cate = request.POST['category']
		user_obj = User.objects.get(username=request.user)
		upload_video = VideoPost(user=user_obj, title=title, desc=desc, video_file=video_file, thumbnail=thumb_nail, category=cate)
		upload_video.save()
		messages.success(request, 'Video has been uploaded.')

	return render(request, 'upload_video.html')


def watch_video(request, video_id):
	try:
		video_obj = VideoPost.objects.get(id=video_id)
	except ObjectDoesNotExist:
		return render(request, '404.html')
	try:
		session_obj = User.objects.get(username=request.user.username)
	except:
		messages.warning(request, 'You are not login to watch this video.')
		return redirect('home')

	video_comments = Comment.objects.filter(post=video_obj).order_by('-id')

	
	# Increase Views of Video if User visit this page
	
	if request.user not in video_obj.video_views.all():
		video_obj.video_views.add(request.user)


	
	# Increase Likes of Video if User like this video
	
	is_liked = False
	if session_obj in video_obj.likes.all():
		is_liked = True
	else:
		is_liked = False
	params = {'video':video_obj, 'comments': video_comments, 'is_liked':is_liked}
	return render(request, 'watch_video.html', params)
	




def add_comment(request):
	if request.method == 'GET':
		video_id = request.GET['video_id']
		comment = request.GET['comment_text']
		video_obj = VideoPost.objects.get(id=video_id)
		session_obj = User.objects.get(username=request.user.username)
		video_comments = Comment.objects.filter(post=video_obj).order_by('-id')
		create_comment = Comment.objects.create(post=video_obj, user=session_obj, comment=comment)
		create_comment.save()

	return JsonResponse({'comment':create_comment.comment, 'count_comments':video_comments.count()})





def add_like(request, video_id):
	user_obj = User.objects.get(username=request.user.username)
	video_obj = VideoPost.objects.get(id=video_id)
	is_liked = False
	if user_obj in video_obj.likes.all():
		video_obj.likes.remove(user_obj)
		is_liked = True
	else:
		video_obj.likes.add(user_obj)
		is_liked = False
	return JsonResponse({'is_liked':is_liked,'likes_count':video_obj.likes.all().count()})




def profile(request, session_username):
	try:
		session_obj = User.objects.get(username=session_username)
	except ObjectDoesNotExist:
		return render(request, '404.html')
	profile_data = UserData.objects.get_or_create(user=session_obj)[0]
	user_posts = VideoPost.objects.filter(user=session_obj).order_by('-id')

	
	# Category wise Posts
	
	video_cat_science = VideoPost.objects.filter(user=session_obj, category='Science & Techanology').order_by('-id')
	video_cat_blogs = VideoPost.objects.filter(user=session_obj, category='Blogs').order_by('-id')
	video_cat_fashion = VideoPost.objects.filter(user=session_obj, category='Fashion').order_by('-id')
	video_cat_education = VideoPost.objects.filter(user=session_obj, category='Education').order_by('-id')
	video_cat_food = VideoPost.objects.filter(user=session_obj, category='Food').order_by('-id')
	
	subscribed = False
	if request.user in profile_data.subscribers.all():
		subscribed = True
	else:
		subscribed = False
	params = {'subscribed':subscribed,'session_obj':session_obj,'user_data':profile_data, 'videos': user_posts, 'sci': video_cat_science, 'blogs': video_cat_blogs, 'fashion': video_cat_fashion, 'edu':video_cat_education, 'food': video_cat_food}
	return render(request, 'profile.html', params)

def dashboard(request, session_username):
	user_videos = VideoPost.objects.filter(user__username=request.user.username).order_by('-id')
	user_data = UserData.objects.get_or_create(user=User.objects.get(username=request.user.username))[0]
	user_video_likes = 0
	user_videos_views = 0

	for video in user_videos:
		user_video_likes += video.likes.count()
		user_videos_views += video.video_views.count()


	params = {'videos': user_videos, 'user_data': user_data, 'total_likes':user_video_likes, 'total_views': user_videos_views}
	return render(request, 'dashboard.html', params)


def add_sub(request, viewer):
	viewer_obj = UserData.objects.get_or_create(user=User.objects.get(username=viewer))[0]
	subscriber_obj = User.objects.get(username=request.user.username)
	
	subscribed = False
	if subscriber_obj in viewer_obj.subscribers.all():
		viewer_obj.subscribers.remove(subscriber_obj)
		subscribed = True
	else:
		viewer_obj.subscribers.add(subscriber_obj)
		subscribed = False
	
	return JsonResponse({'is_subscribed': subscribed, 'viewer_obj':viewer_obj.subscribers.all().count()})



def edit_video(request, video_id):
	if request.method == 'POST':
		new_title = request.POST['new_title']
		new_desc = request.POST['new_desc']
		new_cate = request.POST['new_cate']

		video_obj = VideoPost.objects.get(id=video_id)
		video_obj.title = new_title
		video_obj.desc = new_desc
		video_obj.category = new_cate
		video_obj.save()
		
		return HttpResponseRedirect(reverse('dashboard', args=[str(request.user.username)]))
	else:
		return HttpResponse('get')




def update_details(request):
	if request.method == 'POST':
		user_data = UserData.objects.get(user=request.user)
		
		aboutText = request.POST['about_text']
		try:
			imgFile = request.FILES['img_field']
			if imgFile:
				user_data.profile_pic = imgFile
				
		except:
			print('some error occured')
		
		
		user_data.about = aboutText
		user_data.save()
	
		return HttpResponseRedirect(reverse('dashboard', args=[str(request.user.username)]))
	return redirect('dashboard')
	


def delete_video(request):
	if request.method == 'GET':
		vid = request.GET['videoId']
		video_obj = VideoPost.objects.get(id=vid)
		video_obj.delete()

		user_videos = VideoPost.objects.filter(user__username=request.user.username)
		user_video_likes = 0
		for video in user_videos:
			user_video_likes += video.likes.count()
		return JsonResponse({'video_id': vid, 'videosCount': user_videos.count(), 'videosLikes': user_video_likes})
	else:
		return JsonResponse({'status': 'not ok'})




def signup(request):
	if request.method == 'POST':
		first_name = request.POST['fname']
		last_name = request.POST['lname']
		mail = request.POST['mail']
		pwd = request.POST['pwd']
		new_user = User.objects.create_user(f'{first_name.lower()}123', mail, pwd)
		new_user.first_name = first_name
		new_user.last_name = last_name
		new_user.save()
		messages.success(request, 'Account has been created successfully.')
	return redirect('home')


def user_login(request):
	if not request.user.is_authenticated:

		if request.method == 'POST':
			uname = request.POST['uname']
			pwd = request.POST['pwd']
			
			check_user = authenticate(username = uname, password = pwd)
			if check_user is not None:
				login(request, check_user)
				return redirect('home')
			else:
				messages.warning(request, 'Invalid Username or Password.')
				return redirect('home')
		return redirect('home')

	else:
		return redirect('home')



def user_logout(request):
	logout(request)
	return redirect('home')

```

# Templates Work
Create a *templates* folder in *main* app and create some HTML templates in this folder.
## 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">

    <!--Animation-->
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>ViralVideo</title>
  </head>
  <body>

{% load static %}
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <div class="container-fluid">
        <a class="navbar-brand" href="{% url 'home' %}">ViralVideo</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 'home' %}">Home</a>
            </li>
            <form class="d-flex" action="{% url 'search' %}" method="get">
              <input class="form-control me-2 mx-4" name="search_query" style="width: 700px;" type="search" placeholder="Search User" aria-label="Search">
              <button class="btn btn-outline-success" type="submit">Search</button>
            </form>
          </ul>
          
          {% if not user.is_authenticated %}
            <button class="btn btn-outline-success mx-3" data-bs-toggle="modal" data-bs-target="#loginModal">Login</button>
            <button class="btn btn-outline-warning" data-bs-toggle="modal" data-bs-target="#signupModal">Signup</button>
          {% else %}
          <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.user}}
            </button>
            <ul class="dropdown-menu dropdown-menu-end dropdown-menu-lg-start">
              <a href="{% url 'profile' request.user.username %}" style="text-decoration:none;"><li><button class="dropdown-item" type="button">Your Channel</button></li></a>
              <a href="{% url 'dashboard' request.user.username %}" style="text-decoration:none;"><li><button class="dropdown-item" type="button">Dashboard</button></li></a>
              <a href="{% url 'upload' %}" style="text-decoration:none;"><li><button class="dropdown-item" type="button">Upload Video</button></li></a>
              <li><hr class="dropdown-divider"></li>
              <a href="{% url 'logout' %}" style="text-decoration:none;"><li class="text-danger"><button class="dropdown-item text-danger" type="button">Logout</button></li></a>
            </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 src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>

   
  </body>
</html>
```

## welcome.html
```html
{% extends 'base.html' %}
{% load static %}

{% block body %}

    <!--Signup Modal-->
    <div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Sign Up</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <form action="{% url 'signup' %}" method="post">
              {% csrf_token %}
              <div class="mb-3">
                <label for="fname" class="form-label">First Name</label>
                <input type="text" class="form-control" id="fname" name="fname">
              </div>
              <div class="mb-3">
                <label for="lname" class="form-label">Last Name</label>
                <input type="text" class="form-control" id="lname" name="lname">
              </div>
              <div class="mb-3">
                <label for="exampleInputEmail1" class="form-label">Email address</label>
                <input type="email" class="form-control" id="exampleInputEmail1" name="mail" aria-describedby="emailHelp">
              </div>
              <div class="mb-3">
                <label for="exampleInputPassword1" class="form-label">Password</label>
                <input type="password" class="form-control" name="pwd" id="exampleInputPassword1">
              </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">Sign Up</button>
              </div>
            </form>
          </div>
         
        </div>
      </div>
    </div>

    <!--Login Modal-->
    <div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Login</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
          </div>
          <div class="modal-body">
            <form action="{% url 'login' %}" method="post">
              {% csrf_token %}
              <div class="mb-3">
                <label for="exampleInputEmail1" class="form-label">User Name</label>
                <input type="text" class="form-control" name="uname" id="exampleInputEmail1" aria-describedby="emailHelp">
              </div>
              <div class="mb-3">
                <label for="exampleInputPassword1" class="form-label">Password</label>
                <input type="password" class="form-control" name="pwd" id="exampleInputPassword1">
              </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">Login</button>
              </div>

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

    <!--Welcome Content-->
    <div class="container-fluid my-2">
      <div class="card bg-success text-white" style="height: 400px;">
        <img src="{% static 'img/bg.jpg' %}" class="card-img" style="height: 400px;" alt="...">
        
      </div>
    </div>

    <div class="container my-3">
      {% for video in videos %}
      <div class="card mb-3" style="max-width: 540px;">
        <div class="row g-0">
          <div class="col-md-4">
            <img src="{% static video.thumbnail.url %}" width="208rem" alt="image">
          </div>
          <div class="col-md-8m mx-4 w-50">
            <div class="card-body">
              <a href="{% url 'watch_video' video.id %}" style="text-decoration: none;">
                <h5 class="card-title">{{video.title}}</h5>
              </a>
              <p class="card-text">{{video.desc}}</p>
              <p class="card-text"><small class="text-muted">{{video.pub_date}}</small></p>
            </div>
          </div>
        </div>
      </div>
      {% endfor %}
    </div>



{% endblock %}
```

## home.html
```html
{% extends 'base.html' %}
{% load static %}

{% block body %}
    <div class="container-fluid">
      <div class="card bg-light text-white">
        <img src="{% static 'img/bg2.jpg' %}" class="card-img" style="height: 350px;" alt="...">
        <div class="card-img-overlay">
          <h2 style="margin-top: 150px; margin-left: 350px;">Viral Your Video Here and get more audience</h2>
        </div>
      </div>
    </div>

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

        {% for video in all_videos %}
        <div class="col-3">
          
          <a href="{% url 'watch_video' video.id %}" style="text-decoration: none;">
            <img src="{% static video.thumbnail.url %}" class="w-100">
          </a>
          <a href="{% url 'watch_video' video.id %}" style="text-decoration: none;">
            <h6>{{video.title}}</h6>  
          </a>
          <span class="text-muted">{{video.video_views.all.count}} views • {{video.pub_date}}</span>

        </div>
        {% endfor %}
       

      <hr>

    </div>


{% endblock %}    
```

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

{% block body%}

<div class="container border py-4 my-4 w-75">
	<form action="{% url 'upload' %}" method="post" enctype="multipart/form-data">
		{% csrf_token %}
		<div class="mb-3">
			<label for="title" class="form-label">Title</label>
			<input type="text" name="title" class="form-control" id="title" required>
		</div>

		<div class="mb-3">
			<label for="desc" class="form-label">Description</label>
			<textarea class="form-control" name="desc" id="desc" style="height: 200px;" required></textarea>
		</div>

		<div class="mb-3">
			<label for="filename" class="form-label">Select Video File</label>
			<input type="file" name="fileName" class="form-control" id="filename" accept="video/*" required>
		</div>

		<div class="mb-3">
			<label for="thumb" class="form-label">Select Thumbnail</label>
			<input type="file" name="thumbnail_img" class="form-control" id="thumb" accept="image/*" required>
		</div>

		<div class="mb-3">
			<label for="title" class="form-label">Select Category</label>
			<select class="form-control" name="category">
				<option>Science & Techanology</option>
				<option>Fashion</option>
				<option>Food</option>
				<option>Education</option>
				<option>Blogs</option>
			</select>
		</div>

		
		<button type="submit" class="btn btn-primary">Upload</button>
	</form>
</div>

{% endblock %}
```

## watch_video.html
```html
{% extends 'base.html' %}
{% load static %}

{% block body %}
<div class="row">
  <div class="col-8">
    <div class="container py-2 my-4 w-auto" style="position: absolute; left:100px;">
      <div id="carouselExampleSlidesOnly" class="carousel slide" data-bs-ride="carousel">
        <div class="carousel-inner">
          <div class="carousel-item active">

            <video width="750" controls>
              <source src="{% static video.video_file.url %}" type="video/mp4">
            </video>

            </div>

          </div>
        </div>

        <div class="card w-auto">
          <div class="card-body">
            <h5 class="card-title">{{video.title}}</h5>
            <span class="badge rounded-pill bg-info text-dark">{{video.category}}</span>
            <div class="row">
              <div class="col-8">
                <span class="text-muted">{{video.video_views.all.count}} views • {{video.pub_date}}</span>
              </div>
              <div class="col">
              
              {% if is_liked %}
              
              <a id="like_btn" class="btn btn-outline-danger mx-3"><span id="count_likes">{{video.likes.all.count}}</span>&nbsp&nbsp<span id="like_icon"><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"/>
              </svg>
              </span></a>
              {% else %}
              
              <a id="like_btn" class="btn btn-outline-danger mx-3"><span id="count_likes">{{video.likes.all.count}}</span>&nbsp&nbsp<span id="like_icon"><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>
              </span></a>
              {% endif %}
            
          </div>
        </div>
      </div>
    </div>

    <div class="card my-2">
      <div class="card-header">
          <h6><b>DESCRIPTION</b></h6>
      </div>
      
      <div class="card-body">
        <pre><p>{{video.desc}}</p></pre>
      </div>
    </div>

  </div>
</div>



<div class="col-3" style="margin-left: 0px; width: 400px;">
  
  <div class="container my-3">
    <h3>Up Next</h3>

    <div class="list-group my-2">
      {% for v in video.user.videopost_set.all %}
      <a href="{% url 'watch_video' v.id %}" class="list-group-item list-group-item-action" aria-current="true">
        <div class="d-flex w-100 justify-content-between">
          <h5 class="mb-1">{{v.title}}</h5>
          <small>{{v.pub_date}}</small>
        </div>
        <p class="mb-1">{{v.desc}}</p>
        <small>Donec id elit non mi porta.</small>
      </a>
      {% endfor %}
     

    </div>

  </div>

  <div class="container my-4">
    <!--Comments of this video-->
    <div class="accordion accordion-flush" id="accordionFlushExample">
      <div class="accordion-item">
        <h2 class="accordion-header" id="flush-headingTwo">
          <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapseTwo" aria-expanded="false" aria-controls="flush-collapseTwo">
            <b>COMMENTS (<span id='count_comment'>{{comments.count}}</span>)</b>
          </button>
        </h2>
        <div id="flush-collapseTwo" class="accordion-collapse collapse" aria-labelledby="flush-headingTwo" data-bs-parent="#accordionFlushExample">
          <div class="container my-2">
            <ul class="list-group" id="menu">
              {% for comment in comments %}
              <b>{{comment}}</b>  
              <li class="list-group-item">{{comment.comment}}</li>
              {% endfor %}
            </ul>
          </div>
          <div class="accordion-body">
            <form id="my_form">
              <textarea class="form-control" name="comment" id="comment" placeholder="Write your comment..."></textarea>
              <input class="btn btn-outline-success my-3" id="send_btn" type="submit" value="Comment">
            </form>

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

    </div>
  </div>

</div>
</div>


<script type="text/javascript">

var send_btn = $('#send_btn');
send_btn.on('click', function(event){
  event.preventDefault();
  var comment = $('#comment').val();
  var ul_menu = $('#menu');
  var count_comment = $('#count_comment');

  $.ajax({
    type: 'GET',
    url: '{% url "add_comment" %}',
    data: {comment_text: comment, video_id: '{{video.id}}'},
    dataType: 'json',
    success: function(data){
      if(data.comment)
      {
        var comment_res = data.comment;
        var li_html = "<b>{{request.user}}</b><li class='list-group-item'>"+comment_res+"</li>";

        ul_menu.prepend(li_html);
        count_comment.text(data.count_comments);
        $('#my_form').trigger('reset');

      }

    }

  });
});
</script>


<script type="text/javascript">
var like_btn = $('#like_btn');
like_btn.on('click', function(event){
  event.preventDefault();
  var count_likes = $('#count_likes');
  var like_icon = $('#like_icon');

  $.ajax({
    url: '{% url "add_like" video.id %}',
    data: {},
    dataType: 'json',
    success: function(data){
      if(data.is_liked)
      {
        like_icon.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>');
        count_likes.text(data.likes_count);
      }
      else
      {
        
        like_icon.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"/>');
       count_likes.text(data.likes_count);
     }

   }
 });
});

</script>

{% endblock %}
```

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

{% block body %}
<!--Profile Image and Name-->
<div class="container my-4">
  <div class="container">
    <div class="row">
      <div class="col-3">
        <img src="{% static user_data.profile_pic.url %}" class="img-thumbnail" style="width: 150px;height: 200px;"> 

      </div>
      <div class="col">
        <h2 style="margin-top: 80px;" >{{session_obj.first_name}} {{session_obj.last_name}}</h2>
        <span class="text-muted"><span class="text-muted" id="count">{{user_data.subscribers.count}}</span> Subscribers</span>
        {% if session_obj != request.user %}
        {% if subscribed %}
        <a id="sub_btn" class="btn btn-outline-danger mx-3">Unsubscribe</a>
        {% else %}
        <a id="sub_btn" class="btn btn-outline-danger mx-3">Subscribe</a>
        {% endif %}
        {% endif %}
      </div>

    </div>
  </div>
</div>
<!--End of Profile Image and Name-->

<hr>
<div class="container">
  <ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item" role="presentation">
      <a class="nav-link active" id="home-tab" data-bs-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
    </li>
    <li class="nav-item" role="presentation">
      <a class="nav-link" id="profile-tab" data-bs-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Videos</a>
    </li>
    <li class="nav-item" role="presentation">
      <a class="nav-link" id="contact-tab" data-bs-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">About</a>
    </li>
  </ul>
  <div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
      <h3 class="my-3">Category wise videos</h3>
      <hr>

      {% if sci %}
      <div class="row">
        <h4 class="text-primary">Science & Technology</h4>

        {% for v in sci %}
        <div class="col-3">
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><img src="{% static v.thumbnail.url %}" style="width: 100%;" class="img-thumbnail"></a>
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><h6>{{v.title}}</h6></a>
          <span class="text-muted">{{v.video_views.all.count}} views • {{v.pub_date}}</span>
        </div>
        {% endfor %}

      </div>
      <hr>
      {% endif %}



      {% if blogs %}
      <div class="row">
        <h4 class="text-primary">Blogs</h4>

        {% for v in blogs %}
        <div class="col-3">
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><img src="{% static v.thumbnail.url %}" style="width: 100%;" class="img-thumbnail"></a>
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><h6>{{v.title}}</h6></a>
          <span class="text-muted">{{v.video_views.all.count}} views • {{v.pub_date}}</span>
        </div>
        {% endfor %}

      </div>
      <hr>
      {% endif %}




      {% if food %}
      <div class="row">
        <h4 class="text-primary">Food</h4>

        {% for v in food%}
        <div class="col-3">
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><img src="{% static v.thumbnail.url %}" class="img-thumbnail w-75"></a>
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><h6>{{v.title}}</h6></a>
          <span class="text-muted">{{v.video_views.all.count}} views • {{v.pub_date}}</span>
        </div>
        {% endfor %}       

      </div>
      <hr>
      {% endif %}


      {% if edu %}
      <div class="row">
        <h4 class="text-primary">Education</h4>

        {% for v in edu%}
        <div class="col-3">
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><img src="{% static v.thumbnail.url %}" class="img-thumbnail w-75"></a>
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><h6>{{v.title}}</h6></a>
          <span class="text-muted">{{v.video_views.all.count}} views • {{v.pub_date}}</span>
        </div>
        {% endfor %}       

      </div>
      <hr>
      {% endif %}


      {% if fashion %}
      <div class="row">
        <h4 class="text-primary">Fashion</h4>

        {% for v in fashion %}
        <div class="col-3">
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><img src="{% static v.thumbnail.url %}" class="img-thumbnail w-75"></a>
          <a href="{% url 'watch_video' v.id %}" style="text-decoration: none;"><h4>{{v.title}}</h4></a>
          <span class="text-muted">{{v.video_views.all.count}} views • {{v.pub_date}}</span>
        </div>
        {% endfor %}       

      </div>
      <hr>
      {% endif %}



    </div>
    <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
      <div class="container">
        <h3 class="my-3">Uploads</h3>
        <div class="row my-3">
          {% if videos %}
          {% for video in videos %}
          <div class="col-3">
            <a href="{% url 'watch_video' video.id %}" style="text-decoration: none;"><img src="{% static video.thumbnail.url %}" style="width: 100%;" class="img-thumbnail"></a>
            <a href="{% url 'watch_video' video.id %}" style="text-decoration: none;"><h6>{{video.title}}</h6></a>
            <span class="text-muted">{{video.video_views.all.count}} views • {{video.pub_date}}</span>
          </div>
          {% endfor %}
          {% else %}
          <h3>No Videos.</h3>
          {% endif %}
        </div>
        <hr>

      </div>
    </div>


    <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">
      <div class="container my-4">
        <p><b>Description</b></p>
        <pre style="font-family: tahoma; letter-spacing: 1px;"><p>{{user_data.about}}</p></pre>
        <hr>

        <p><b>Details</b></p>
        <p>Email: </p>
        <a href="mailto:{{session_obj.email}}"><p>{{session_obj.email}}</p></a>
        <hr>

        <p><b>Links: </b></p>
        <p>Instagram</p>
        <p>Github</p>
        <p>Twitter</p>
        <p>Facebook</p>
        <hr>
      </div>
    </div>
  </div>
</div>


<script type="text/javascript">
var btn = $('#sub_btn');
var count = $('#count');  
// btn.text('Subscribe');
btn.on('click', function(event){
  event.preventDefault();

  $.ajax({
    type: 'GET',
    url: '{% url "add_subscriber" session_obj.username %}',
    dataType: 'json',
    success: function(data){
      if(data.is_subscribed)
      {
          // alert(data.is_subscribed);
          btn.text('Subscribe');
          count.text(data.viewer_obj);
          console.log(data.viewer_obj);
        }
        else
        {
         // alert(data.is_subscribed); 
         btn.text('Unsubscribe');
         count.text(data.viewer_obj);
         console.log(data.viewer_obj);
       }
     }

   });
});


</script>
{% endblock %}
```

## dashboard.html
```html
{% extends 'base.html' %}
{% load static %}

{% block body %}
<div class="container my-3 py-3">
	<div class="row">
		<div class="col-sm-3">
			<div class="card" style="width: 15rem;">
				<div class="card border border-danger bg-danger text-light" style="width: 15rem;">
					<div class="card-body">
						<h2 class="card-title text-center"><span id="text_v_likes">{{total_likes}}</span> Likes</h2>
					</div>
				</div>
			</div>
		</div>
		<div class="col-sm-3">
			<div class="card" style="width: 15rem;">
				<div class="card border border-danger bg-danger text-light" style="width: 15rem;">
					<div class="card-body">
						<h2 class="card-title text-center">{{user_data.subscribers.all.count}} Subscribers</h2>
					</div>
				</div>
			</div>
		</div>
		<div class="col-sm-3">
			<div class="card" style="width: 15rem;">
				<div class="card border border-danger bg-danger text-light" style="width: 15rem;">
					<div class="card-body">
						<h2 class="card-title text-center"><span id='text_v_count'>{{videos.count}}</span> Videos</h2>
					</div>
				</div>
			</div>
		</div>
		<div class="col-sm-3">
			<div class="card" style="width: 15rem;">
				<div class="card border border-danger bg-danger text-light" style="width: 15rem;">
					<div class="card-body">
						<h2 class="card-title text-center"><span id='text_v_count'>{{total_views}}</span> Views</h2>
					</div>
				</div>
			</div>
		</div>
	</div>

</div>



<div class="container">
	<div class="d-flex align-items-start">
		<div class="nav flex-column nav-pills px-4 py-4 me-3 border" id="v-pills-tab" role="tablist" aria-orientation="vertical">
			<a class="nav-link active h5" id="v-pills-home-tab" data-bs-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Videos</a>
			<a class="nav-link h5" id="v-pills-profile-tab" data-bs-toggle="pill" href="#v-pills-profile" role="tab" aria-controls="v-pills-profile" aria-selected="false">Profile</a>
		</div>


		<div class="tab-content" id="v-pills-tabContent">
			<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
				<div class="container">
					{% for video in videos %}
					<div class="card my-3 border-dark" id="{{video.id}}">
						<h5 class="card-header">{{video.title}}</h5>
						<div class="card-body">
							<img src="{% static video.thumbnail.url %}" class="img-thumbnail w-25">			
							<p class="card-text">{{video.desc|truncatewords:5}}</p>
							<a href="{% url 'watch_video' video.id %}" class="btn btn-primary">Watch Now</a>
							<span class="mx-4">
								<button class="btn btn-danger">
									<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>
									<b>{{video.likes.count}}</b>
								</button>

								<button class="btn btn-warning">
									<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye-fill" viewBox="0 0 16 16">
										<path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/>
										<path d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/>
									</svg>
									<b>{{video.video_views.count}}</b>
								</button>

								<button class="btn btn-info">
									<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-vector-pen" viewBox="0 0 16 16">
										<path fill-rule="evenodd" d="M10.646.646a.5.5 0 0 1 .708 0l4 4a.5.5 0 0 1 0 .708l-1.902 1.902-.829 3.313a1.5 1.5 0 0 1-1.024 1.073L1.254 14.746 4.358 4.4A1.5 1.5 0 0 1 5.43 3.377l3.313-.828L10.646.646zm-1.8 2.908l-3.173.793a.5.5 0 0 0-.358.342l-2.57 8.565 8.567-2.57a.5.5 0 0 0 .34-.357l.794-3.174-3.6-3.6z"/>
										<path fill-rule="evenodd" d="M2.832 13.228L8 9a1 1 0 1 0-1-1l-4.228 5.168-.026.086.086-.026z"/>
									</svg>
									<b>{{video.comment_set.all.count}}</b>
								</button>

							</span>
							<a class="btn btn-outline-danger mx-2 del_btn" id="{{video.id}}" style="float: right;">Delete</a>
							<a href="#" class="btn btn-outline-success mx-2" data-bs-toggle="modal" data-bs-target="#exampleModal{{video.id}}" style="float: right;">Edit</a>
							<!-- Button trigger modal -->
							

							<!-- Edit Video Modal -->
							<div class="modal fade" id="exampleModal{{video.id}}" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
								<div class="modal-dialog">
									<div class="modal-content">
										<div class="modal-header">
											<h5 class="modal-title" id="exampleModalLabel">Edit Video Details</h5>
											<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
										</div>
										<div class="modal-body">
											<form action="{% url 'edit_video' video.id %}" method="post">
												{% csrf_token %}
												<div class="form-floating">
													<input type="text" placeholder="Title" name="new_title" class="form-control my-2 new_title" id="new_title{{video.id}}" value="{{video.title}}">
													<label for="floatingInput" >Title</label>
												</div>
												<div class="form-floating">
													<textarea class="form-control my-2 new_desc" id="new_desc{{video.id}}" placeholder="Description" name="new_desc" style="height: 300px;">{{video.desc}}</textarea>
													<label for="floatingInput">Description</label>
												</div>
												<div class="form-floating">
												<select name="new_cate" class="form-control new_cate" id="new_cate{{video.id}}" name="category">
													<option>{{video.category}}</option>
													<option>Science & Techanology</option>
													<option>Fashion</option>
													<option>Food</option>
													<option>Education</option>
													<option>Blogs</option>
												</select>
												<label for="floatingInput">Category</label>
												</div>
												<div class="modal-footer">
													<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
													<button type="submit" id="edit_btn{{video.id}}" class="btn btn-primary edit_btn">Save changes</button>
												</div>
											</form>
										</div>
										
									</div>
								</div>
							</div>
						</div>
					</div>
					{% endfor %}

				</div>
			</div>


			<div class="tab-pane fade " style="width:800px;" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-profile-tab">
				<div class="container">

					<div class="container">
						<h3>Additional Data</h3>
						<form action="{% url 'update_details' %}" method="post" enctype="multipart/form-data">
							{% csrf_token %}
						<div class="row">
							<div class="col-sm-8 my-auto">
								
									<input type="file" name="img_field" accept="image/*" class="form-control">

								</div>
								<div class="col-sm-4">
									<b><label>Current Profile Pic</label></b>
									
									<img src="{% static user_data.profile_pic.url %}" class="rounded" style="width: 150px; height: 200px;" alt="{{user_data.profile_pic}}">
									
								</div>
							</div>

							<div class="row">
								<div class="col-sm-8">
									<b><label for="about_text">About</label></b>
									<textarea placeholder="About yourself..." class="form-control" style="height: 100px;" name="about_text">{{user_data.about}}</textarea>
								</div>
							</div>
							<input type="submit" id="update_btn" value="Update" class="btn btn-outline-success my-3">
						</form>
					</div>
					<hr>
					<div class="container">
						<h3 class="text-danger">Danger Zone</h3>
						<form>
							<input type="text" name="" placeholder="Type Your Username to Verify" class="form-control">
							<input type="submit" name="" value="Deactivate Your Account" class="btn btn-outline-danger my-3">
						</form>
						
					</div>
					
				</div>
			</div>



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





<script type="text/javascript">
var btn = $('.del_btn');
btn.on('click',function(event){
	event.preventDefault();
	var vid = $(this).attr('id');
	var v_count = $('#text_v_count');
	var v_likes = $('#text_v_likes');
		
		$.ajax({
			type: 'GET',
			url: '{% url "delete_video" %}',
			data: {videoId: vid},
			dataType: 'json',
			success: function(data){
				if(data.video_id)
				{
					var vid = data.video_id;
					$('div').remove('#'+vid);
					v_count.text(data.videosCount);
					v_likes.text(data.videosLikes);
				}
				

			}
		});	
	});


</script>

{% endblock %}

```
## search_page.html
```html
{% extends 'base.html' %}
{% load static %}
{% block body %}
<div class="container my-4">
	<h3>Search Results: </h3>
	{% if user_obj %}
	<div class="row">
	{% for user in user_obj %}
	<div class="col-4">
	<div class="card my-3" style="width: 18rem;">
		<img src="{% static user.userdata.profile_pic.url %}" class="img-thumbnail card-img-top" style="height: 250px;" alt="...">
		<div class="card-body">
			<h5 class="card-title">{{user.username}}</h5>
			<p class="card-text">{{user.userdata.about|truncatewords:6}}</p>
			<a href="{% url 'profile' user.username %}" class="btn btn-primary">View Profile</a>
		</div>
	</div>
	</div>
	{% endfor %}
	</div>
	{% else %}
	<div class="container">
		<h5>No Results Found.</h5>
	</div>
	{% endif %}
</div>	
{% endblock %}
```

## 404.html
```html
{% extends 'base.html' %}
{% block body %}

	<div class="container py-4 w-25 text-center bg-danger" style="margin-left: 40%; margin-top: 100px;">
		<h1 class="animate__animated animate__swing">404</h1>
		Not Found
	</div>


{% endblock %}

```

That's it.

 If you face any problem related to the source code than comment below. 

I have worked very hard on this project. So I request you to support my hard work.