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()}")