Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions job_portal/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone

class User(AbstractUser):
is_recruiter = models.BooleanField(default=False)
is_candidate = models.BooleanField(default=False)
phone = models.CharField(max_length=15, blank=True)
profile_pic = models.ImageField(upload_to='profiles/', blank=True)

def __str__(self):
return self.username

class Company(models.Model):
name = models.CharField(max_length=200)
description = models.TextField(blank=True)
website = models.URLField(blank=True)
logo = models.ImageField(upload_to='company_logos/', blank=True)
location = models.CharField(max_length=100)
established_date = models.DateField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.name

class Meta:
verbose_name_plural = 'Companies'

class Job(models.Model):
EMPLOYMENT_TYPE_CHOICES = [
('full_time', 'Full Time'),
('part_time', 'Part Time'),
('contract', 'Contract'),
('internship', 'Internship'),
]

title = models.CharField(max_length=200)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
description = models.TextField()
requirements = models.TextField()
location = models.CharField(max_length=100)
salary_min = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
salary_max = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True)
employment_type = models.CharField(max_length=20, choices=EMPLOYMENT_TYPE_CHOICES)
posted_by = models.ForeignKey(User, on_delete=models.CASCADE)
posted_date = models.DateTimeField(auto_now_add=True)
deadline = models.DateTimeField()
is_active = models.BooleanField(default=True)

def __str__(self):
return f"{self.title} at {self.company.name}"

class Meta:
ordering = ['-posted_date']

class Application(models.Model):
STATUS_CHOICES = [
('pending', 'Pending'),
('reviewed', 'Reviewed'),
('shortlisted', 'Shortlisted'),
('rejected', 'Rejected'),
('hired', 'Hired'),
]

job = models.ForeignKey(Job, on_delete=models.CASCADE)
candidate = models.ForeignKey(User, on_delete=models.CASCADE)
resume = models.FileField(upload_to='resumes/')
cover_letter = models.TextField(blank=True)
applied_date = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')

def __str__(self):
return f"{self.candidate.username} - {self.job.title}"

class Meta:
unique_together = ['job', 'candidate']
ordering = ['-applied_date']

class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
skills = models.TextField(blank=True)
experience = models.TextField(blank=True)
education = models.TextField(blank=True)
linkedin_url = models.URLField(blank=True)
github_url = models.URLField(blank=True)
portfolio_url = models.URLField(blank=True)

def __str__(self):
return f"{self.user.username}'s Profile"
17 changes: 17 additions & 0 deletions job_portal/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.urls import path, include
from . import views

urlpatterns = [
path('', views.home, name='home'),
path('about/', views.about, name='about'),
path('contact/', views.contact, name='contact'),
path('jobs/', views.jobs, name='jobs'),
path('job/<int:pk>/', views.job_detail, name='job_detail'),
path('companies/', views.companies, name='companies'),
path('company/<int:pk>/', views.company_detail, name='company_detail'),
path('dashboard/', views.dashboard, name='dashboard'),
path('superadmin/', views.superadmin_dashboard, name='superadmin_dashboard'),
path('login/', views.user_login, name='login'),
path('logout/', views.user_logout, name='logout'),
path('register/', views.register, name='register'),
]
148 changes: 148 additions & 0 deletions job_portal/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.http import JsonResponse, HttpResponse
from django.db.models import Count, Q
from django.utils import timezone
from datetime import datetime, timedelta
import json
from .models import *
from .forms import *

def home(request):
context = {
'jobs': Job.objects.filter(is_active=True)[:6],
'companies': Company.objects.all()[:6],
}
return render(request, 'home.html', context)

def is_superuser(user):
return user.is_superuser

@login_required
@user_passes_test(is_superuser)
def superadmin_dashboard(request):
# Get basic counts
total_companies = Company.objects.count()
total_recruiters = User.objects.filter(is_recruiter=True).count()
total_candidates = User.objects.filter(is_candidate=True).count()
total_jobs = Job.objects.count()

# Get registration data for the last 30 days
end_date = timezone.now()
start_date = end_date - timedelta(days=30)

registration_labels = []
registration_data = []

for i in range(30):
date = start_date + timedelta(days=i)
label = date.strftime('%m/%d')
count = User.objects.filter(
date_joined__date=date.date()
).count()
registration_labels.append(label)
registration_data.append(count)

# Get application data for the last 7 days
application_labels = []
application_data = []

for i in range(7):
date = end_date - timedelta(days=6-i)
label = date.strftime('%m/%d')
# Assuming you have an Application model
try:
count = Application.objects.filter(
applied_date__date=date.date()
).count()
except:
count = 0
application_labels.append(label)
application_data.append(count)

# Get companies with additional stats
companies = Company.objects.annotate(
recruiters_count=Count('user', filter=Q(user__is_recruiter=True)),
active_jobs=Count('job', filter=Q(job__is_active=True)),
total_applications=Count('job__application')
)[:10]

context = {
'total_companies': total_companies,
'total_recruiters': total_recruiters,
'total_candidates': total_candidates,
'total_jobs': total_jobs,
'registration_labels': json.dumps(registration_labels),
'registration_data': json.dumps(registration_data),
'application_labels': json.dumps(application_labels),
'application_data': json.dumps(application_data),
'companies': companies,
}

return render(request, 'superadmin/dashboard.html', context)

# Your existing views continue here...
def about(request):
return render(request, 'about.html')

def contact(request):
return render(request, 'contact.html')

def jobs(request):
jobs = Job.objects.filter(is_active=True)
context = {'jobs': jobs}
return render(request, 'jobs.html', context)

def job_detail(request, pk):
job = get_object_or_404(Job, pk=pk)
context = {'job': job}
return render(request, 'job_detail.html', context)

def companies(request):
companies = Company.objects.all()
context = {'companies': companies}
return render(request, 'companies.html', context)

def company_detail(request, pk):
company = get_object_or_404(Company, pk=pk)
jobs = Job.objects.filter(company=company, is_active=True)
context = {'company': company, 'jobs': jobs}
return render(request, 'company_detail.html', context)

@login_required
def dashboard(request):
if request.user.is_superuser:
return redirect('superadmin_dashboard')
elif request.user.is_recruiter:
return render(request, 'recruiter_dashboard.html')
else:
return render(request, 'candidate_dashboard.html')

def user_login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('dashboard')
else:
messages.error(request, 'Invalid credentials')
return render(request, 'registration/login.html')

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

def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
messages.success(request, 'Account created successfully')
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form': form})
Loading