Merge pull request #28 from WajahatKanju/feature/auto-populate-data
Dummy Data Generation Utility
This commit is contained in:
commit
6c8bc0a1a5
@ -1,212 +1,215 @@
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth.models import AbstractUser, UserManager
|
||||
from django.conf import settings
|
||||
|
||||
from django.db.models import Q
|
||||
from PIL import Image
|
||||
|
||||
from course.models import Program
|
||||
from .validators import ASCIIUsernameValidator
|
||||
|
||||
|
||||
# LEVEL_COURSE = "Level course"
|
||||
BACHLOAR_DEGREE = "Bachloar"
|
||||
MASTER_DEGREE = "Master"
|
||||
|
||||
LEVEL = (
|
||||
# (LEVEL_COURSE, "Level course"),
|
||||
(BACHLOAR_DEGREE, "Bachloar Degree"),
|
||||
(MASTER_DEGREE, "Master Degree"),
|
||||
)
|
||||
|
||||
FATHER = "Father"
|
||||
MOTHER = "Mother"
|
||||
BROTHER = "Brother"
|
||||
SISTER = "Sister"
|
||||
GRAND_MOTHER = "Grand mother"
|
||||
GRAND_FATHER = "Grand father"
|
||||
OTHER = "Other"
|
||||
|
||||
RELATION_SHIP = (
|
||||
(FATHER, "Father"),
|
||||
(MOTHER, "Mother"),
|
||||
(BROTHER, "Brother"),
|
||||
(SISTER, "Sister"),
|
||||
(GRAND_MOTHER, "Grand mother"),
|
||||
(GRAND_FATHER, "Grand father"),
|
||||
(OTHER, "Other"),
|
||||
)
|
||||
|
||||
|
||||
class CustomUserManager(UserManager):
|
||||
def search(self, query=None):
|
||||
queryset = self.get_queryset()
|
||||
if query is not None:
|
||||
or_lookup = (
|
||||
Q(username__icontains=query)
|
||||
| Q(first_name__icontains=query)
|
||||
| Q(last_name__icontains=query)
|
||||
| Q(email__icontains=query)
|
||||
)
|
||||
queryset = queryset.filter(
|
||||
or_lookup
|
||||
).distinct() # distinct() is often necessary with Q lookups
|
||||
return queryset
|
||||
|
||||
def get_student_count(self):
|
||||
return self.model.objects.filter(is_student=True).count()
|
||||
|
||||
def get_lecturer_count(self):
|
||||
return self.model.objects.filter(is_lecturer=True).count()
|
||||
|
||||
def get_superuser_count(self):
|
||||
return self.model.objects.filter(is_superuser=True).count()
|
||||
|
||||
|
||||
GENDERS = (("M", "Male"), ("F", "Female"))
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
is_student = models.BooleanField(default=False)
|
||||
is_lecturer = models.BooleanField(default=False)
|
||||
is_parent = models.BooleanField(default=False)
|
||||
is_dep_head = models.BooleanField(default=False)
|
||||
gender = models.CharField(max_length=1, choices=GENDERS, blank=True, null=True)
|
||||
phone = models.CharField(max_length=60, blank=True, null=True)
|
||||
address = models.CharField(max_length=60, blank=True, null=True)
|
||||
picture = models.ImageField(
|
||||
upload_to="profile_pictures/%y/%m/%d/", default="default.png", null=True
|
||||
)
|
||||
email = models.EmailField(blank=True, null=True)
|
||||
|
||||
username_validator = ASCIIUsernameValidator()
|
||||
|
||||
objects = CustomUserManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ("-date_joined",)
|
||||
|
||||
@property
|
||||
def get_full_name(self):
|
||||
full_name = self.username
|
||||
if self.first_name and self.last_name:
|
||||
full_name = self.first_name + " " + self.last_name
|
||||
return full_name
|
||||
|
||||
def __str__(self):
|
||||
return "{} ({})".format(self.username, self.get_full_name)
|
||||
|
||||
@property
|
||||
def get_user_role(self):
|
||||
if self.is_superuser:
|
||||
role = "Admin"
|
||||
elif self.is_student:
|
||||
role = "Student"
|
||||
elif self.is_lecturer:
|
||||
role = "Lecturer"
|
||||
elif self.is_parent:
|
||||
role = "Parent"
|
||||
|
||||
return role
|
||||
|
||||
def get_picture(self):
|
||||
try:
|
||||
return self.picture.url
|
||||
except:
|
||||
no_picture = settings.MEDIA_URL + "default.png"
|
||||
return no_picture
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("profile_single", kwargs={"id": self.id})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
try:
|
||||
img = Image.open(self.picture.path)
|
||||
if img.height > 300 or img.width > 300:
|
||||
output_size = (300, 300)
|
||||
img.thumbnail(output_size)
|
||||
img.save(self.picture.path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
if self.picture.url != settings.MEDIA_URL + "default.png":
|
||||
self.picture.delete()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class StudentManager(models.Manager):
|
||||
def search(self, query=None):
|
||||
qs = self.get_queryset()
|
||||
if query is not None:
|
||||
or_lookup = Q(level__icontains=query) | Q(program__icontains=query)
|
||||
qs = qs.filter(
|
||||
or_lookup
|
||||
).distinct() # distinct() is often necessary with Q lookups
|
||||
return qs
|
||||
|
||||
|
||||
class Student(models.Model):
|
||||
student = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
# id_number = models.CharField(max_length=20, unique=True, blank=True)
|
||||
level = models.CharField(max_length=25, choices=LEVEL, null=True)
|
||||
program = models.ForeignKey(Program, on_delete=models.CASCADE, null=True)
|
||||
|
||||
objects = StudentManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ("-student__date_joined",)
|
||||
|
||||
def __str__(self):
|
||||
return self.student.get_full_name
|
||||
|
||||
@classmethod
|
||||
def get_gender_count(cls):
|
||||
males_count = Student.objects.filter(student__gender="M").count()
|
||||
females_count = Student.objects.filter(student__gender="F").count()
|
||||
|
||||
return {"M": males_count, "F": females_count}
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("profile_single", kwargs={"id": self.id})
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.student.delete()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class Parent(models.Model):
|
||||
"""
|
||||
Connect student with their parent, parents can
|
||||
only view their connected students information
|
||||
"""
|
||||
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
student = models.OneToOneField(Student, null=True, on_delete=models.SET_NULL)
|
||||
first_name = models.CharField(max_length=120)
|
||||
last_name = models.CharField(max_length=120)
|
||||
phone = models.CharField(max_length=60, blank=True, null=True)
|
||||
email = models.EmailField(blank=True, null=True)
|
||||
|
||||
# What is the relationship between the student and
|
||||
# the parent (i.e. father, mother, brother, sister)
|
||||
relation_ship = models.TextField(choices=RELATION_SHIP, blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("-user__date_joined",)
|
||||
|
||||
def __str__(self):
|
||||
return self.user.username
|
||||
|
||||
|
||||
class DepartmentHead(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
department = models.ForeignKey(Program, on_delete=models.CASCADE, null=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("-user__date_joined",)
|
||||
|
||||
def __str__(self):
|
||||
return "{}".format(self.user)
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth.models import AbstractUser, UserManager
|
||||
from django.conf import settings
|
||||
|
||||
from django.db.models import Q
|
||||
from PIL import Image
|
||||
|
||||
from course.models import Program
|
||||
from .validators import ASCIIUsernameValidator
|
||||
|
||||
|
||||
# LEVEL_COURSE = "Level course"
|
||||
BACHLOAR_DEGREE = "Bachloar"
|
||||
MASTER_DEGREE = "Master"
|
||||
|
||||
LEVEL = (
|
||||
# (LEVEL_COURSE, "Level course"),
|
||||
(BACHLOAR_DEGREE, "Bachloar Degree"),
|
||||
(MASTER_DEGREE, "Master Degree"),
|
||||
)
|
||||
|
||||
FATHER = "Father"
|
||||
MOTHER = "Mother"
|
||||
BROTHER = "Brother"
|
||||
SISTER = "Sister"
|
||||
GRAND_MOTHER = "Grand mother"
|
||||
GRAND_FATHER = "Grand father"
|
||||
OTHER = "Other"
|
||||
|
||||
RELATION_SHIP = (
|
||||
(FATHER, "Father"),
|
||||
(MOTHER, "Mother"),
|
||||
(BROTHER, "Brother"),
|
||||
(SISTER, "Sister"),
|
||||
(GRAND_MOTHER, "Grand mother"),
|
||||
(GRAND_FATHER, "Grand father"),
|
||||
(OTHER, "Other"),
|
||||
)
|
||||
|
||||
|
||||
class CustomUserManager(UserManager):
|
||||
def search(self, query=None):
|
||||
queryset = self.get_queryset()
|
||||
if query is not None:
|
||||
or_lookup = (
|
||||
Q(username__icontains=query)
|
||||
| Q(first_name__icontains=query)
|
||||
| Q(last_name__icontains=query)
|
||||
| Q(email__icontains=query)
|
||||
)
|
||||
queryset = queryset.filter(
|
||||
or_lookup
|
||||
).distinct() # distinct() is often necessary with Q lookups
|
||||
return queryset
|
||||
|
||||
|
||||
GENDERS = (("M", "Male"), ("F", "Female"))
|
||||
|
||||
|
||||
class User(AbstractUser):
|
||||
is_student = models.BooleanField(default=False)
|
||||
is_lecturer = models.BooleanField(default=False)
|
||||
is_parent = models.BooleanField(default=False)
|
||||
is_dep_head = models.BooleanField(default=False)
|
||||
gender = models.CharField(max_length=1, choices=GENDERS, blank=True, null=True)
|
||||
phone = models.CharField(max_length=60, blank=True, null=True)
|
||||
address = models.CharField(max_length=60, blank=True, null=True)
|
||||
picture = models.ImageField(
|
||||
upload_to="profile_pictures/%y/%m/%d/", default="default.png", null=True
|
||||
)
|
||||
email = models.EmailField(blank=True, null=True)
|
||||
|
||||
username_validator = ASCIIUsernameValidator()
|
||||
|
||||
objects = CustomUserManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ("-date_joined",)
|
||||
|
||||
@property
|
||||
def get_full_name(self):
|
||||
full_name = self.username
|
||||
if self.first_name and self.last_name:
|
||||
full_name = self.first_name + " " + self.last_name
|
||||
return full_name
|
||||
|
||||
@classmethod
|
||||
def get_student_count(cls):
|
||||
return cls.objects.filter(is_student=True).count()
|
||||
|
||||
@classmethod
|
||||
def get_lecturer_count(cls):
|
||||
return cls.objects.filter(is_lecturer=True).count()
|
||||
|
||||
@classmethod
|
||||
def get_superuser_count(cls):
|
||||
return cls.objects.filter(is_superuser=True).count()
|
||||
|
||||
def __str__(self):
|
||||
return "{} ({})".format(self.username, self.get_full_name)
|
||||
|
||||
@property
|
||||
def get_user_role(self):
|
||||
if self.is_superuser:
|
||||
role = "Admin"
|
||||
elif self.is_student:
|
||||
role = "Student"
|
||||
elif self.is_lecturer:
|
||||
role = "Lecturer"
|
||||
elif self.is_parent:
|
||||
role = "Parent"
|
||||
|
||||
return role
|
||||
|
||||
def get_picture(self):
|
||||
try:
|
||||
return self.picture.url
|
||||
except:
|
||||
no_picture = settings.MEDIA_URL + "default.png"
|
||||
return no_picture
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("profile_single", kwargs={"id": self.id})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
try:
|
||||
img = Image.open(self.picture.path)
|
||||
if img.height > 300 or img.width > 300:
|
||||
output_size = (300, 300)
|
||||
img.thumbnail(output_size)
|
||||
img.save(self.picture.path)
|
||||
except:
|
||||
pass
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
if self.picture.url != settings.MEDIA_URL + "default.png":
|
||||
self.picture.delete()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class StudentManager(models.Manager):
|
||||
def search(self, query=None):
|
||||
qs = self.get_queryset()
|
||||
if query is not None:
|
||||
or_lookup = Q(level__icontains=query) | Q(program__icontains=query)
|
||||
qs = qs.filter(
|
||||
or_lookup
|
||||
).distinct() # distinct() is often necessary with Q lookups
|
||||
return qs
|
||||
|
||||
|
||||
class Student(models.Model):
|
||||
student = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
# id_number = models.CharField(max_length=20, unique=True, blank=True)
|
||||
level = models.CharField(max_length=25, choices=LEVEL, null=True)
|
||||
program = models.ForeignKey(Program, on_delete=models.CASCADE, null=True)
|
||||
|
||||
objects = StudentManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ("-student__date_joined",)
|
||||
|
||||
def __str__(self):
|
||||
return self.student.get_full_name
|
||||
|
||||
@classmethod
|
||||
def get_gender_count(cls):
|
||||
males_count = Student.objects.filter(student__gender="M").count()
|
||||
females_count = Student.objects.filter(student__gender="F").count()
|
||||
|
||||
return {"M": males_count, "F": females_count}
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse("profile_single", kwargs={"id": self.id})
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.student.delete()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class Parent(models.Model):
|
||||
"""
|
||||
Connect student with their parent, parents can
|
||||
only view their connected students information
|
||||
"""
|
||||
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
student = models.OneToOneField(Student, null=True, on_delete=models.SET_NULL)
|
||||
first_name = models.CharField(max_length=120)
|
||||
last_name = models.CharField(max_length=120)
|
||||
phone = models.CharField(max_length=60, blank=True, null=True)
|
||||
email = models.EmailField(blank=True, null=True)
|
||||
|
||||
# What is the relationship between the student and
|
||||
# the parent (i.e. father, mother, brother, sister)
|
||||
relation_ship = models.TextField(choices=RELATION_SHIP, blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("-user__date_joined",)
|
||||
|
||||
def __str__(self):
|
||||
return self.user.username
|
||||
|
||||
|
||||
class DepartmentHead(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
department = models.ForeignKey(Program, on_delete=models.CASCADE, null=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("-user__date_joined",)
|
||||
|
||||
def __str__(self):
|
||||
return "{}".format(self.user)
|
||||
@ -37,6 +37,7 @@ AUTH_USER_MODEL = "accounts.User"
|
||||
DJANGO_APPS = [
|
||||
"jet.dashboard",
|
||||
"jet",
|
||||
"django_extensions",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
-r base.txt
|
||||
|
||||
psycopg2-binary==2.9.5 # https://github.com/psycopg/psycopg2
|
||||
|
||||
# Code quality
|
||||
# ------------------------------------------------------------------------------
|
||||
black==22.12.0 # https://github.com/psf/black
|
||||
-r base.txt
|
||||
|
||||
psycopg2-binary==2.9.5 # https://github.com/psycopg/psycopg2
|
||||
|
||||
# Code quality
|
||||
# ------------------------------------------------------------------------------
|
||||
black==22.12.0 # https://github.com/psf/black
|
||||
|
||||
# Django Extensions
|
||||
django-extensions==3.1.3 # https://github.com/django-extensions/django-extensions
|
||||
0
scripts/__init__.py
Normal file
0
scripts/__init__.py
Normal file
165
scripts/generate_fake_accounts_data.py
Normal file
165
scripts/generate_fake_accounts_data.py
Normal file
@ -0,0 +1,165 @@
|
||||
import os
|
||||
import django
|
||||
from typing import List, Tuple
|
||||
from django.utils import timezone
|
||||
from faker import Faker
|
||||
from factory.django import DjangoModelFactory
|
||||
from factory import SubFactory, LazyAttribute, Iterator
|
||||
from django_extensions.management.commands import runscript
|
||||
|
||||
# Set up Django environment
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
||||
django.setup()
|
||||
|
||||
from accounts.models import User, Student, Parent, DepartmentHead, LEVEL, RELATION_SHIP
|
||||
from course.models import Program
|
||||
|
||||
fake = Faker()
|
||||
|
||||
class UserFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating User instances with optional flags.
|
||||
|
||||
Attributes:
|
||||
username (str): The generated username.
|
||||
first_name (str): The generated first name.
|
||||
last_name (str): The generated last name.
|
||||
email (str): The generated email.
|
||||
date_joined (datetime): The current date and time.
|
||||
phone (str): The generated phone number.
|
||||
address (str): The generated address.
|
||||
is_student (bool): Flag indicating if the user is a student.
|
||||
is_lecturer (bool): Flag indicating if the user is a lecturer.
|
||||
is_parent (bool): Flag indicating if the user is a parent.
|
||||
is_dep_head (bool): Flag indicating if the user is a department head.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
||||
username: str = LazyAttribute(lambda x: fake.user_name())
|
||||
first_name: str = LazyAttribute(lambda x: fake.first_name())
|
||||
last_name: str = LazyAttribute(lambda x: fake.last_name())
|
||||
email: str = LazyAttribute(lambda x: fake.email())
|
||||
date_joined: timezone.datetime = timezone.now()
|
||||
phone: str = LazyAttribute(lambda x: fake.phone_number())
|
||||
address: str = LazyAttribute(lambda x: fake.address())
|
||||
is_student: bool = False
|
||||
is_lecturer: bool = False
|
||||
is_parent: bool = False
|
||||
is_dep_head: bool = False
|
||||
|
||||
@classmethod
|
||||
def _create(cls, model_class: type, *args, **kwargs) -> User:
|
||||
"""
|
||||
Create a User instance with optional flags.
|
||||
|
||||
Args:
|
||||
model_class (type): The class of the model to create.
|
||||
|
||||
Returns:
|
||||
User: The created User instance.
|
||||
"""
|
||||
user: User = super()._create(model_class, *args, **kwargs)
|
||||
|
||||
# Set the appropriate flags based on the user type
|
||||
if cls.is_student:
|
||||
user.is_student = True
|
||||
elif cls.is_parent:
|
||||
user.is_parent = True
|
||||
|
||||
user.save()
|
||||
return user
|
||||
|
||||
class ProgramFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Program instances.
|
||||
|
||||
Attributes:
|
||||
title (str): The generated program title.
|
||||
summary (str): The generated summary.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Program
|
||||
|
||||
title: str = LazyAttribute(lambda x: fake.sentence(nb_words=3))
|
||||
summary: str = LazyAttribute(lambda x: fake.text())
|
||||
|
||||
@classmethod
|
||||
def _create(cls, model_class: type, *args, **kwargs) -> Program:
|
||||
"""
|
||||
Create a Program instance using get_or_create to avoid duplicates.
|
||||
|
||||
Args:
|
||||
model_class (type): The class of the model to create.
|
||||
|
||||
Returns:
|
||||
Program: The created Program instance.
|
||||
"""
|
||||
program, created = Program.objects.get_or_create(title=kwargs.get("title"), defaults=kwargs)
|
||||
return program
|
||||
|
||||
class StudentFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Student instances with associated User and Program.
|
||||
|
||||
Attributes:
|
||||
student (User): The associated User instance.
|
||||
level (str): The level of the student.
|
||||
program (Program): The associated Program instance.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Student
|
||||
|
||||
student: User = SubFactory(UserFactory, is_student=True)
|
||||
level: str = Iterator([choice[0] for choice in LEVEL])
|
||||
program: Program = SubFactory(ProgramFactory)
|
||||
|
||||
class ParentFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Parent instances with associated User, Student, and Program.
|
||||
|
||||
Attributes:
|
||||
user (User): The associated User instance.
|
||||
student (Student): The associated Student instance.
|
||||
first_name (str): The generated first name.
|
||||
last_name (str): The generated last name.
|
||||
phone (str): The generated phone number.
|
||||
email (str): The generated email.
|
||||
relation_ship (str): The relationship with the student.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Parent
|
||||
|
||||
user: User = SubFactory(UserFactory, is_parent=True)
|
||||
student: Student = SubFactory(StudentFactory)
|
||||
first_name: str = LazyAttribute(lambda x: fake.first_name())
|
||||
last_name: str = LazyAttribute(lambda x: fake.last_name())
|
||||
phone: str = LazyAttribute(lambda x: fake.phone_number())
|
||||
email: str = LazyAttribute(lambda x: fake.email())
|
||||
relation_ship: str = Iterator([choice[0] for choice in RELATION_SHIP])
|
||||
|
||||
|
||||
def generate_fake_accounts_data(num_programs: int, num_students: int, num_parents: int) -> None:
|
||||
"""
|
||||
Generate fake data for Programs, Students, Parents, and DepartmentHeads.
|
||||
|
||||
Args:
|
||||
num_programs (int): Number of programs to generate.
|
||||
num_students (int): Number of students to generate.
|
||||
num_parents (int): Number of parents to generate.
|
||||
"""
|
||||
programs: List[Program] = ProgramFactory.create_batch(num_programs)
|
||||
students: List[Student] = StudentFactory.create_batch(num_students)
|
||||
parents: List[Parent] = ParentFactory.create_batch(num_parents)
|
||||
|
||||
print(f"Created {len(programs)} programs.")
|
||||
print(f"Created {len(students)} students.")
|
||||
print(f"Created {len(parents)} parents.")
|
||||
|
||||
|
||||
generate_fake_accounts_data(10, 10, 10)
|
||||
|
||||
114
scripts/generate_fake_core_data.py
Normal file
114
scripts/generate_fake_core_data.py
Normal file
@ -0,0 +1,114 @@
|
||||
import os
|
||||
import django
|
||||
import random
|
||||
from typing import List
|
||||
from django.utils import timezone
|
||||
from faker import Faker
|
||||
from factory.django import DjangoModelFactory
|
||||
from factory import SubFactory, LazyAttribute, Iterator
|
||||
from core.models import ActivityLog, NewsAndEvents, Session, Semester, SEMESTER, POST
|
||||
|
||||
# Set up Django environment
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
||||
django.setup()
|
||||
|
||||
fake = Faker()
|
||||
|
||||
class NewsAndEventsFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating NewsAndEvents instances.
|
||||
|
||||
Attributes:
|
||||
title (str): The generated title for the news or event.
|
||||
summary (str): The generated summary.
|
||||
posted_as (str): The type of the post, either 'News' or 'Event'.
|
||||
updated_date (datetime): The generated date and time of update.
|
||||
upload_time (datetime): The generated date and time of upload.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = NewsAndEvents
|
||||
|
||||
title: str = LazyAttribute(lambda x: fake.sentence(nb_words=4))
|
||||
summary: str = LazyAttribute(lambda x: fake.paragraph(nb_sentences=3))
|
||||
posted_as: str = fake.random_element(elements=[choice[0] for choice in POST])
|
||||
updated_date: timezone.datetime = fake.date_time_this_year()
|
||||
upload_time: timezone.datetime = fake.date_time_this_year()
|
||||
|
||||
class SessionFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Session instances.
|
||||
|
||||
Attributes:
|
||||
session (str): The generated session name.
|
||||
is_current_session (bool): Flag indicating if the session is current.
|
||||
next_session_begins (date): The date when the next session begins.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Session
|
||||
|
||||
session: str = LazyAttribute(lambda x: fake.sentence(nb_words=2))
|
||||
is_current_session: bool = fake.boolean(chance_of_getting_true=50)
|
||||
next_session_begins = LazyAttribute(lambda x: fake.future_datetime())
|
||||
|
||||
|
||||
class SemesterFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Semester instances.
|
||||
|
||||
Attributes:
|
||||
semester (str): The generated semester name.
|
||||
is_current_semester (bool): Flag indicating if the semester is current.
|
||||
session (Session): The associated session.
|
||||
next_semester_begins (date): The date when the next semester begins.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Semester
|
||||
|
||||
semester: str = fake.random_element(elements=[choice[0] for choice in SEMESTER])
|
||||
is_current_semester: bool = fake.boolean(chance_of_getting_true=50)
|
||||
session: Session = SubFactory(SessionFactory)
|
||||
next_semester_begins = LazyAttribute(lambda x: fake.future_datetime())
|
||||
|
||||
class ActivityLogFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating ActivityLog instances.
|
||||
|
||||
Attributes:
|
||||
message (str): The generated log message.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = ActivityLog
|
||||
|
||||
message: str = LazyAttribute(lambda x: fake.text())
|
||||
|
||||
|
||||
def generate_fake_core_data(num_news_and_events: int, num_sessions: int, num_semesters: int, num_activity_logs: int) -> None:
|
||||
"""
|
||||
Generate fake data for core models: NewsAndEvents, Session, Semester, and ActivityLog.
|
||||
|
||||
Args:
|
||||
num_news_and_events (int): Number of NewsAndEvents instances to generate.
|
||||
num_sessions (int): Number of Session instances to generate.
|
||||
num_semesters (int): Number of Semester instances to generate.
|
||||
num_activity_logs (int): Number of ActivityLog instances to generate.
|
||||
"""
|
||||
# Generate fake NewsAndEvents instances
|
||||
news_and_events: List[NewsAndEvents] = NewsAndEventsFactory.create_batch(num_news_and_events)
|
||||
print(f"Generated {num_news_and_events} NewsAndEvents instances.")
|
||||
|
||||
# Generate fake Session instances
|
||||
sessions: List[Session] = SessionFactory.create_batch(num_sessions)
|
||||
print(f"Generated {num_sessions} Session instances.")
|
||||
|
||||
# Generate fake Semester instances
|
||||
semesters: List[Semester] = SemesterFactory.create_batch(num_semesters)
|
||||
print(f"Generated {num_semesters} Semester instances.")
|
||||
|
||||
# Generate fake ActivityLog instances
|
||||
activity_logs: List[ActivityLog] = ActivityLogFactory.create_batch(num_activity_logs)
|
||||
print(f"Generated {num_activity_logs} ActivityLog instances.")
|
||||
|
||||
179
scripts/generate_fake_data.py
Normal file
179
scripts/generate_fake_data.py
Normal file
@ -0,0 +1,179 @@
|
||||
from typing import Type
|
||||
from factory.django import DjangoModelFactory
|
||||
from factory import SubFactory, LazyAttribute, Iterator
|
||||
from faker import Faker
|
||||
|
||||
from course.models import Program, Course, CourseAllocation,Upload, UploadVideo,CourseOffer, SEMESTER
|
||||
from accounts.models import User, DepartmentHead
|
||||
from core.models import Session
|
||||
|
||||
from .generate_fake_accounts_data import UserFactory, ProgramFactory
|
||||
from .generate_fake_core_data import SessionFactory
|
||||
|
||||
fake = Faker()
|
||||
|
||||
class DepartmentHeadFactory(DjangoModelFactory):
|
||||
class Meta:
|
||||
model = DepartmentHead
|
||||
|
||||
user = SubFactory(UserFactory)
|
||||
department = SubFactory(ProgramFactory)
|
||||
|
||||
|
||||
class ProgramFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Program instances.
|
||||
|
||||
Attributes:
|
||||
title (str): The generated title for the program.
|
||||
summary (str): The generated summary for the program.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Program
|
||||
|
||||
title: str = LazyAttribute(lambda x: fake.sentence(nb_words=3))
|
||||
summary: str = LazyAttribute(lambda x: fake.paragraph())
|
||||
|
||||
class CourseFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Course instances.
|
||||
|
||||
Attributes:
|
||||
slug (str): The generated slug for the course.
|
||||
title (str): The generated title for the course.
|
||||
code (str): The generated code for the course.
|
||||
credit (int): The generated credit for the course.
|
||||
summary (str): The generated summary for the course.
|
||||
program (Program): The associated program for the course.
|
||||
level (str): The generated level for the course.
|
||||
year (int): The generated year for the course.
|
||||
semester (str): The generated semester for the course.
|
||||
is_elective (bool): The flag indicating if the course is elective.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Course
|
||||
|
||||
slug: str = LazyAttribute(lambda x: fake.slug())
|
||||
title: str = LazyAttribute(lambda x: fake.sentence(nb_words=4))
|
||||
code: str = LazyAttribute(lambda x: fake.unique.word())
|
||||
credit: int = LazyAttribute(lambda x: fake.random_int(min=1, max=6))
|
||||
summary: str = LazyAttribute(lambda x: fake.paragraph())
|
||||
program: Type[Program] = SubFactory(ProgramFactory)
|
||||
level: str = Iterator(["Beginner", "Intermediate", "Advanced"])
|
||||
year: int = LazyAttribute(lambda x: fake.random_int(min=1, max=4))
|
||||
semester: str = Iterator([choice[0] for choice in SEMESTER])
|
||||
is_elective: bool = LazyAttribute(lambda x: fake.boolean())
|
||||
|
||||
class CourseAllocationFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating CourseAllocation instances.
|
||||
|
||||
Attributes:
|
||||
lecturer (User): The associated lecturer for the course allocation.
|
||||
session (Session): The associated session for the course allocation.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = CourseAllocation
|
||||
|
||||
lecturer: Type[User] = SubFactory(UserFactory, is_lecturer=True)
|
||||
session: Type[Session] = SubFactory(SessionFactory)
|
||||
|
||||
class UploadFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating Upload instances.
|
||||
|
||||
Attributes:
|
||||
title (str): The generated title for the upload.
|
||||
course (Course): The associated course for the upload.
|
||||
file (str): The generated file path for the upload.
|
||||
updated_date (datetime): The generated updated date for the upload.
|
||||
upload_time (datetime): The generated upload time for the upload.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Upload
|
||||
|
||||
title: str = LazyAttribute(lambda x: fake.sentence(nb_words=3))
|
||||
course = SubFactory(CourseFactory) # Adjust 'yourapp' with your actual app name
|
||||
file: str = LazyAttribute(lambda x: fake.file_path(extension="pdf"))
|
||||
updated_date = fake.date_time_this_year()
|
||||
upload_time = fake.date_time_this_year()
|
||||
|
||||
class UploadVideoFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating UploadVideo instances.
|
||||
|
||||
Attributes:
|
||||
title (str): The generated title for the video upload.
|
||||
slug (str): The generated slug for the video upload.
|
||||
course (Course): The associated course for the video upload.
|
||||
video (str): The generated video path for the video upload.
|
||||
summary (str): The generated summary for the video upload.
|
||||
timestamp (datetime): The generated timestamp for the video upload.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = UploadVideo
|
||||
|
||||
title: str = LazyAttribute(lambda x: fake.sentence(nb_words=3))
|
||||
slug: str = LazyAttribute(lambda x: fake.slug())
|
||||
course = SubFactory(CourseFactory) # Adjust 'yourapp' with your actual app name
|
||||
video: str = LazyAttribute(lambda x: fake.file_path(extension="mp4"))
|
||||
summary: str = LazyAttribute(lambda x: fake.paragraph())
|
||||
timestamp = fake.date_time_this_year()
|
||||
|
||||
class CourseOfferFactory(DjangoModelFactory):
|
||||
"""
|
||||
Factory for creating CourseOffer instances.
|
||||
|
||||
Attributes:
|
||||
dep_head (DepartmentHead): The associated department head for the course offer.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = CourseOffer
|
||||
|
||||
dep_head = SubFactory(DepartmentHeadFactory)
|
||||
|
||||
|
||||
def generate_fake_course_data(num_programs: int, num_courses: int, num_course_allocations: int, num_uploads: int, num_upload_videos: int, num_course_offers: int) -> None:
|
||||
"""Generate fake data using various factories.
|
||||
|
||||
Args:
|
||||
num_programs (int): Number of fake programs to create.
|
||||
num_courses (int): Number of fake courses to create.
|
||||
num_course_allocations (int): Number of fake course allocations to create.
|
||||
num_uploads (int): Number of fake uploads to create.
|
||||
num_upload_videos (int): Number of fake upload videos to create.
|
||||
num_course_offers (int): Number of fake course offers to create.
|
||||
"""
|
||||
# Generate fake programs
|
||||
programs = ProgramFactory.create_batch(num_programs)
|
||||
print(f"Created {len(programs)} programs.")
|
||||
|
||||
# Generate fake courses
|
||||
courses = CourseFactory.create_batch(num_courses)
|
||||
print(f"Created {len(courses)} courses.")
|
||||
|
||||
# Generate fake course allocations
|
||||
course_allocations = CourseAllocationFactory.create_batch(num_course_allocations)
|
||||
print(f"Created {len(course_allocations)} course allocations.")
|
||||
|
||||
# Generate fake uploads
|
||||
uploads = UploadFactory.create_batch(num_uploads)
|
||||
print(f"Created {len(uploads)} uploads.")
|
||||
|
||||
# Generate fake upload videos
|
||||
upload_videos = UploadVideoFactory.create_batch(num_upload_videos)
|
||||
print(f"Created {len(upload_videos)} upload videos.")
|
||||
|
||||
# Generate fake course offers
|
||||
course_offers = CourseOfferFactory.create_batch(num_course_offers)
|
||||
print(f"Created {len(course_offers)} course offers.")
|
||||
|
||||
|
||||
|
||||
generate_fake_course_data(10, 10, 10, 10, 10, 10)
|
||||
Loading…
x
Reference in New Issue
Block a user