151 lines
6.4 KiB
Python
151 lines
6.4 KiB
Python
from pathlib import Path
|
|
from rich import print
|
|
from django.conf import settings
|
|
import os
|
|
import uuid
|
|
import random
|
|
from datetime import date, timedelta
|
|
from django.core.management.base import BaseCommand
|
|
from django.utils import timezone
|
|
from time import sleep
|
|
from faker import Faker
|
|
|
|
from recruitment.models import JobPosting, Candidate, Source, FormTemplate
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Seeds the database with initial JobPosting and Candidate data using Faker.'
|
|
|
|
def add_arguments(self, parser):
|
|
# Add argument for the number of jobs to create, default is 5
|
|
parser.add_argument(
|
|
'--jobs',
|
|
type=int,
|
|
help='The number of JobPostings to create.',
|
|
default=5,
|
|
)
|
|
# Add argument for the number of candidates to create, default is 20
|
|
parser.add_argument(
|
|
'--candidates',
|
|
type=int,
|
|
help='The number of Candidate applications to create.',
|
|
default=20,
|
|
)
|
|
|
|
def handle(self, *args, **options):
|
|
# Get the desired counts from command line arguments
|
|
jobs_count = options['jobs']
|
|
candidates_count = options['candidates']
|
|
|
|
# Initialize Faker
|
|
fake = Faker('en_US') # Using en_US for general data, can be changed if needed
|
|
|
|
self.stdout.write("--- Starting Database Seeding ---")
|
|
self.stdout.write(f"Preparing to create {jobs_count} jobs and {candidates_count} candidates.")
|
|
|
|
# 1. Clear existing data (Optional, but useful for clean seeding)
|
|
JobPosting.objects.all().delete()
|
|
FormTemplate.objects.all().delete()
|
|
Candidate.objects.all().delete()
|
|
self.stdout.write(self.style.WARNING("Existing JobPostings and Candidates cleared."))
|
|
|
|
# 2. Create Foreign Key dependency: Source
|
|
default_source, created = Source.objects.get_or_create(
|
|
name="Career Website",
|
|
defaults={'name': 'Career Website'}
|
|
)
|
|
self.stdout.write(f"Using Source: {default_source.name}")
|
|
|
|
# --- Helper Chooser Lists ---
|
|
JOB_TYPES = [choice[0] for choice in JobPosting.JOB_TYPES]
|
|
WORKPLACE_TYPES = [choice[0] for choice in JobPosting.WORKPLACE_TYPES]
|
|
STATUS_CHOICES = [choice[0] for choice in JobPosting.STATUS_CHOICES]
|
|
DEPARTMENTS = ["Technology", "Marketing", "Finance", "HR", "Sales", "Research", "Operations"]
|
|
REPORTING_TO = ["CTO", "HR Manager", "Department Head", "VP of Sales"]
|
|
|
|
|
|
# 3. Generate JobPostings
|
|
created_jobs = []
|
|
for i in range(jobs_count):
|
|
# Dynamic job details
|
|
sleep(random.randint(4,10))
|
|
title = fake.job()
|
|
department = random.choice(DEPARTMENTS)
|
|
is_faculty = random.random() < 0.1 # 10% chance of being a faculty job
|
|
job_type = "FACULTY" if is_faculty else random.choice([t for t in JOB_TYPES if t != "FACULTY"])
|
|
|
|
# Generate realistic salary range
|
|
base_salary = random.randint(50, 200) * 1000
|
|
salary_range = f"${base_salary:,.0f} - ${base_salary + random.randint(10, 50) * 1000:,.0f}"
|
|
|
|
# Random dates
|
|
start_date = fake.date_object()
|
|
deadline_date = start_date + timedelta(days=random.randint(14, 60))
|
|
|
|
# Use Faker's HTML generation for CKEditor5 fields
|
|
description_html = f"<h1>{title} Role</h1>" + "".join(f"<p>{fake.paragraph(nb_sentences=3, variable_nb_sentences=True)}</p>" for _ in range(3))
|
|
qualifications_html = "<ul>" + "".join(f"<li>{fake.sentence(nb_words=6)}</li>" for _ in range(random.randint(3, 5))) + "</ul>"
|
|
benefits_html = f"<p>Standard benefits include: {fake.sentence(nb_words=8)}</p>"
|
|
instructions_html = f"<p>To apply, visit: {fake.url()} and follow the steps below.</p>"
|
|
|
|
job_data = {
|
|
"title": title,
|
|
"department": department,
|
|
"job_type": job_type,
|
|
"workplace_type": random.choice(WORKPLACE_TYPES),
|
|
"location_country": "Saudia Arabia",
|
|
"description": description_html,
|
|
"qualifications": qualifications_html,
|
|
"application_deadline": deadline_date,
|
|
"status": random.choice(STATUS_CHOICES),
|
|
}
|
|
|
|
job = JobPosting.objects.create(
|
|
**job_data
|
|
)
|
|
# FormTemplate.objects.create(job=job, name=f"{job.title} Form", description=f"Form for {job.title}",is_active=True)
|
|
created_jobs.append(job)
|
|
self.stdout.write(self.style.SUCCESS(f'Created JobPosting {i+1}/{jobs_count}: {job.title}'))
|
|
|
|
|
|
# 4. Generate Candidates
|
|
if created_jobs:
|
|
for i in range(candidates_count):
|
|
sleep(random.randint(4,10))
|
|
# Link candidate to a random job
|
|
target_job = random.choice(created_jobs)
|
|
print(target_job)
|
|
first_name = fake.first_name()
|
|
last_name = fake.last_name()
|
|
path = os.path.join(settings.BASE_DIR,'media/resumes/')
|
|
|
|
# path = Path('media/resumes/') # <-- CORRECT
|
|
file = random.choice(os.listdir(path))
|
|
print(file)
|
|
# file = os.path.abspath(file)
|
|
candidate_data = {
|
|
"first_name": first_name,
|
|
"last_name": last_name,
|
|
# Create a plausible email based on name
|
|
"email": f"{first_name.lower()}.{last_name.lower()}@{fake.domain_name()}",
|
|
"phone": "0566987458",
|
|
"address": fake.address(),
|
|
# Placeholder resume path
|
|
"resume": 'resumes/'+ file,
|
|
"job": target_job,
|
|
}
|
|
print(candidate_data)
|
|
|
|
Candidate.objects.create(**candidate_data)
|
|
self.stdout.write(self.style.NOTICE(
|
|
f'Created Candidate {i+1}/{candidates_count}: {first_name} for {target_job.title[:30]}...'
|
|
))
|
|
print("done")
|
|
else:
|
|
self.stdout.write(self.style.WARNING("No jobs created, skipping candidate generation."))
|
|
|
|
|
|
self.stdout.write(self.style.SUCCESS('\n--- Database Seeding Complete! ---'))
|
|
|
|
# Summary output
|
|
self.stdout.write(f"Total JobPostings created: {JobPosting.objects.count()}")
|
|
self.stdout.write(f"Total Candidates created: {Candidate.objects.count()}") |