diff --git a/api/dashboard/error_log/error_view.py b/api/dashboard/error_log/error_view.py index 21156703..5b150562 100644 --- a/api/dashboard/error_log/error_view.py +++ b/api/dashboard/error_log/error_view.py @@ -1,3 +1,4 @@ +import logging import os from decouple import config @@ -81,6 +82,8 @@ def post(self, request, log_name): class LoggerAPI(APIView): + authentication_classes = [CustomizePermission] + @role_required( [RoleType.ADMIN.value, RoleType.FELLOW.value, RoleType.TECH_TEAM.value] ) @@ -95,3 +98,11 @@ def get(self, request): log_handler = logHandler() formatted_errors = log_handler.parse_logs(log_data) return CustomResponse(response=formatted_errors).get_success_response() + + @role_required( + [RoleType.ADMIN.value, RoleType.FELLOW.value, RoleType.TECH_TEAM.value] + ) + def patch(self, request, error_id): + logger = logging.getLogger("django") + logger.error(f"PATCHED : {error_id}") + return CustomResponse(response="Updated patch list").get_success_response() diff --git a/api/dashboard/error_log/log_helper.py b/api/dashboard/error_log/log_helper.py index c20787c8..afea889d 100644 --- a/api/dashboard/error_log/log_helper.py +++ b/api/dashboard/error_log/log_helper.py @@ -32,6 +32,11 @@ def parse_logs(self, log_data: str) -> list[dict]: Returns: list[dict]: formatted errors """ + self.patch_pattern = ( + r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) ERROR PATCHED : (\w+)" + ) + self.patched_errors = self.extract_patches(log_data) + # Extract all logs in string format matches = reversed(re.findall(self.log_pattern, log_data, re.DOTALL)) formatted_errors = {} @@ -43,6 +48,12 @@ def parse_logs(self, log_data: str) -> list[dict]: return formatted_errors.values() + def extract_patches(self, log_data): + return { + patch[2]: self.get_formatted_time(patch[1]) + for patch in re.finditer(self.patch_pattern, log_data) + } + def extract_log_entry(self, error: str) -> dict: """fetch the value from the details of how to find it provided by the regex @@ -58,6 +69,7 @@ def extract_log_entry(self, error: str) -> dict: for key, value in values.items(): entry_type = self.log_entries[key]["type"] + if entry_type == datetime: result_dict[key] = self.get_formatted_time(value) elif entry_type == dict and value: @@ -116,23 +128,35 @@ def get_patterns(self) -> list: values = self.log_entries.values() return [value["regex"] for value in values] - def aggregate_log_entry(self, formatted_errors: list[dict], log_entry: dict) -> None: + def already_patched(self, log_entry: dict) -> bool: + """checks if log entry id is in patched + errors and its timestamp is before the error was patched + """ + return ( + log_entry["id"] in self.patched_errors + and log_entry["timestamp"] < self.patched_errors[log_entry["id"]] + ) + + def aggregate_log_entry( + self, formatted_errors: list[dict], log_entry: dict + ) -> None: """combines all fetched error into one Args: formatted_errors (list[dict]): the list to add everything into log_entry (dict): current log entry """ - log_id = log_entry["id"] - log_keys = self.log_entries.keys() - if log_id not in formatted_errors: - formatted_errors[log_id] = { - key: [] if key != "id" else log_id for key in log_keys - } - for key in log_keys: - if ( - key != "id" - and log_entry[key] - and log_entry[key] not in formatted_errors[log_id][key] - ): - formatted_errors[log_id][key].append(log_entry[key]) + if not self.already_patched(log_entry): + log_id = log_entry["id"] + log_keys = self.log_entries.keys() + if log_id not in formatted_errors: + formatted_errors[log_id] = { + key: [] if key != "id" else log_id for key in log_keys + } + for key in log_keys: + if ( + key != "id" + and log_entry[key] + and log_entry[key] not in formatted_errors[log_id][key] + ): + formatted_errors[log_id][key].append(log_entry[key]) \ No newline at end of file diff --git a/api/dashboard/error_log/urls.py b/api/dashboard/error_log/urls.py index aa0a5475..f9e37ccf 100644 --- a/api/dashboard/error_log/urls.py +++ b/api/dashboard/error_log/urls.py @@ -4,6 +4,7 @@ urlpatterns = [ path('', error_view.LoggerAPI.as_view()), + path('patch//', error_view.LoggerAPI.as_view()), path('/', error_view.DownloadErrorLogAPI.as_view()), path('view//', error_view.ViewErrorLogAPI.as_view()), path('clear//', error_view.ClearErrorLogAPI.as_view()), diff --git a/api/dashboard/lc/dash_lc_serializer.py b/api/dashboard/lc/dash_lc_serializer.py index f76a83d4..038eaa12 100644 --- a/api/dashboard/lc/dash_lc_serializer.py +++ b/api/dashboard/lc/dash_lc_serializer.py @@ -466,7 +466,7 @@ def get_previous_meetings(self, obj): return previous_meetings -class LearningCircleDataSerializer(serializers.ModelSerializer): +class LearningCircleStatsSerializer(serializers.ModelSerializer): interest_group = serializers.SerializerMethodField() college = serializers.SerializerMethodField() learning_circle = serializers.SerializerMethodField() diff --git a/api/dashboard/lc/dash_lc_view.py b/api/dashboard/lc/dash_lc_view.py index a4e3053f..e91eabf6 100644 --- a/api/dashboard/lc/dash_lc_view.py +++ b/api/dashboard/lc/dash_lc_view.py @@ -17,7 +17,7 @@ from utils.utils import send_template_mail, DateTimeUtils from .dash_lc_serializer import LearningCircleSerializer, LearningCircleCreateSerializer, LearningCircleDetailsSerializer, \ LearningCircleUpdateSerializer, LearningCircleJoinSerializer, \ - LearningCircleMainSerializer, LearningCircleNoteSerializer, LearningCircleDataSerializer, \ + LearningCircleMainSerializer, LearningCircleNoteSerializer, LearningCircleStatsSerializer, \ LearningCircleMemberListSerializer, MeetRecordsCreateEditDeleteSerializer, IgTaskDetailsSerializer, \ ScheduleMeetingSerializer, ListAllMeetRecordsSerializer, AddMemberSerializer @@ -90,7 +90,7 @@ def post(self, request): ).get_success_response() -class LearningCircleDataAPI(APIView): +class LearningCircleStatsAPI(APIView): """ API endpoint for retrieving basic data about all learning circles. @@ -103,7 +103,7 @@ class LearningCircleDataAPI(APIView): def get(self, request): learning_circle = LearningCircle.objects.all() - serializer = LearningCircleDataSerializer( + serializer = LearningCircleStatsSerializer( learning_circle, many=False ) diff --git a/api/dashboard/lc/urls.py b/api/dashboard/lc/urls.py index bbb3196a..5f13f2aa 100644 --- a/api/dashboard/lc/urls.py +++ b/api/dashboard/lc/urls.py @@ -4,6 +4,7 @@ urlpatterns = [ path('user-list/', dash_lc_view.UserLearningCircleListApi.as_view(), name='main'), # list all lc's of user + path('stats/', dash_lc_view.LearningCircleStatsAPI.as_view(), name='data'), path('/details/', dash_lc_view.LearningCircleDetailsApi.as_view(), name='lc-detailed'), # individual ls details # dashboard search listing path('/schedule-meet/', dash_lc_view.ScheduleMeetAPI.as_view(), name='schedule-meet'), @@ -25,7 +26,6 @@ path('list/', dash_lc_view.LearningCircleMainApi.as_view(), name='list'), # public page listing path('list-all/', dash_lc_view.TotalLearningCircleListApi.as_view(), name='list-all'), # dashboard search listing - # path('data/', dash_lc_view.LearningCircleDataAPI.as_view(), name='data'), # path('list-members//', dash_lc_view.LearningCircleListMembersApi.as_view(), name='list-members'), # path('invite/', dash_lc_view.LearningCircleInviteLeadAPI.as_view()), # path('meet-record/list-all//', dash_lc_view.SingleReportDetailAPI.as_view(), name='list-all-meet-record'), # optim diff --git a/api/dashboard/profile/profile_serializer.py b/api/dashboard/profile/profile_serializer.py index 919d778e..96120200 100644 --- a/api/dashboard/profile/profile_serializer.py +++ b/api/dashboard/profile/profile_serializer.py @@ -387,7 +387,7 @@ def create_karma_activity_log(task_title, karma_value): task = TaskList.objects.filter(title=task_title).first() if task: if karma_value > 0: - KarmaActivityLog.objects.create( + karma_log = KarmaActivityLog.objects.create( task_id=task.id, karma=karma_value, user_id=user_id, @@ -401,13 +401,17 @@ def create_karma_activity_log(task_title, karma_value): dl = WebHookActions.SEPARATOR.value discord_id = User.objects.get(id=user_id).discord_id - value = f"{task.hashtag}{dl}{karma_value}{dl}{discord_id}{dl}{task.id}" + value = f"{task.hashtag}{dl}{karma_value}{dl}{discord_id}{dl}{karma_log.id}" DiscordWebhooks.general_updates( WebHookCategory.KARMA_INFO.value, WebHookActions.UPDATE.value, value ) + else: + KarmaActivityLog.objects.filter( + task_id=task.id, user_id=user_id + ).delete() Wallet.objects.filter(user_id=user_id).update( karma=F("karma") + karma_value, updated_by_id=user_id diff --git a/api/dashboard/profile/profile_view.py b/api/dashboard/profile/profile_view.py index b7928699..ced0c293 100644 --- a/api/dashboard/profile/profile_view.py +++ b/api/dashboard/profile/profile_view.py @@ -61,11 +61,8 @@ def patch(self, request): def delete(self, request): user_id = JWTUtils.fetch_user_id(request) - user = User.objects.get(id=user_id) - user.deleted_by = user - user.deleted_at = DateTimeUtils.get_current_utc_time() - user.save() - + user = User.objects.get(id=user_id).delete() + return CustomResponse( general_message="User deleted successfully" ).get_success_response() diff --git a/api/dashboard/roles/dash_roles_serializer.py b/api/dashboard/roles/dash_roles_serializer.py index 789107d7..a37d6a3e 100644 --- a/api/dashboard/roles/dash_roles_serializer.py +++ b/api/dashboard/roles/dash_roles_serializer.py @@ -38,9 +38,9 @@ def validate(self, attrs): ) if users.count() != len(attrs): raise serializers.ValidationError("One or more user IDs are invalid.") - else: - data["users"] = users - return data + + data["users"] = users + return data def create(self, validated_data): users = validated_data.pop("users") @@ -57,7 +57,7 @@ def create(self, validated_data): validated_data["role"].title, ",".join(list(users.values_list("id", flat=True))), ) - return user_roles_to_create + return user_roles_to_create, validated_data["role"] class RoleDashboardSerializer(serializers.ModelSerializer): diff --git a/api/dashboard/roles/dash_roles_views.py b/api/dashboard/roles/dash_roles_views.py index 97e5942c..6986ba06 100644 --- a/api/dashboard/roles/dash_roles_views.py +++ b/api/dashboard/roles/dash_roles_views.py @@ -173,9 +173,7 @@ def get(self, request, role_id): Lists all the users with a given role """ users = ( - User.objects.filter(user_role_link_user__role__pk=role_id) - .distinct() - .all() + User.objects.filter(user_role_link_user__role__pk=role_id).distinct().all() ) serialized_users = dash_roles_serializer.UserRoleLinkManagementSerializer( users, many=True @@ -204,19 +202,44 @@ def patch(self, request): Assigns a large bunch of users a certain role """ request_data = request.data.copy() - request_data[ - "created_by" - ] = JWTUtils.fetch_user_id(request) + request_data["created_by"] = JWTUtils.fetch_user_id(request) serialized_users = dash_roles_serializer.RoleAssignmentSerializer( data=request_data ) if serialized_users.is_valid(): - serialized_users.save() + users, role = serialized_users.save() return CustomResponse( - general_message="Successfully gave all users the requested role" + general_message=f"Successfully gave {len(users)} users '{role.title}' role" ).get_success_response() return CustomResponse(response=serialized_users.errors).get_failure_response() + @role_required([RoleType.ADMIN.value]) + def delete(self, request): + """ + Removes a role from a large bunch of users + """ + role = Role.objects.get(pk=request.data.get("role")) + user_role_links = UserRoleLink.objects.filter( + user__pk__in=request.data.get("users"), + role=role, + ) + number = user_role_links.count() + + DiscordWebhooks.general_updates( + WebHookCategory.BULK_ROLE.value, + WebHookActions.DELETE.value, + role.title, + ",".join(list(user_role_links.values_list("user_id", flat=True))), + ) + + user_role_links.delete() + + return CustomResponse( + general_message=( + f"Successfully removed the '{role.title}' role from {number} users" + ) + ).get_success_response() + class UserRole(APIView): authentication_classes = [CustomizePermission] @@ -421,12 +444,12 @@ def post(self, request): else: error_rows.append(user_roles_serializer.errors) - for role,user_set in users_by_role.items(): + for role, user_set in users_by_role.items(): DiscordWebhooks.general_updates( WebHookCategory.BULK_ROLE.value, WebHookActions.UPDATE.value, role, - ",".join(user_set) + ",".join(user_set), ) return CustomResponse( diff --git a/api/dashboard/user/dash_user_serializer.py b/api/dashboard/user/dash_user_serializer.py index b99137e4..e00cf758 100644 --- a/api/dashboard/user/dash_user_serializer.py +++ b/api/dashboard/user/dash_user_serializer.py @@ -99,7 +99,7 @@ class UserDetailsSerializer(serializers.ModelSerializer): organizations = serializers.SerializerMethodField(read_only=True) interest_groups = serializers.SerializerMethodField(read_only=True) role = serializers.SerializerMethodField(read_only=True) - district = serializers.CharField(source="district.name", allow_null=True) + district = serializers.CharField(source="district.id", allow_null=True) class Meta: model = User @@ -251,6 +251,7 @@ class Meta: "department", "graduation_year", "admin", + "district" ] def to_representation(self, instance): diff --git a/api/dashboard/user/dash_user_views.py b/api/dashboard/user/dash_user_views.py index 9efe00fa..88d704be 100644 --- a/api/dashboard/user/dash_user_views.py +++ b/api/dashboard/user/dash_user_views.py @@ -58,10 +58,8 @@ def delete(self, request, user_id): return CustomResponse( general_message="User Not Available" ).get_failure_response() - - user.deleted_by = User.objects.get(pk=JWTUtils.fetch_user_id(request)) - user.deleted_at = DateTimeUtils.get_current_utc_time() - user.save() + + user.delete() return CustomResponse( general_message="User deleted successfully" diff --git a/api/register/register_helper.py b/api/register/register_helper.py index 0c539dc0..3966248c 100644 --- a/api/register/register_helper.py +++ b/api/register/register_helper.py @@ -1,25 +1,7 @@ import decouple import requests -from db.user import User from utils.exception import CustomException -from utils.response import CustomResponse - - -def get_full_name(first_name, last_name): - return f"{first_name}{last_name or ''}".replace(" ", "").lower()[:85] - - -def generate_muid(first_name, last_name): - full_name = get_full_name(first_name, last_name) - muid = f"{full_name}@mulearn" - - counter = 0 - while User.objects.filter(muid=muid).exists(): - counter += 1 - muid = f"{full_name}-{counter}@mulearn" - - return muid def get_auth_token(muid, password): @@ -32,4 +14,4 @@ def get_auth_token(muid, password): if response.get("statusCode") != 200: raise CustomException(response.get("message")) - return response.get("response") + return response.get("response") \ No newline at end of file diff --git a/api/register/serializers.py b/api/register/serializers.py index 7aff8e49..92326a7d 100644 --- a/api/register/serializers.py +++ b/api/register/serializers.py @@ -231,9 +231,6 @@ class UserSerializer(serializers.ModelSerializer): def create(self, validated_data): role = validated_data.pop("role", None) - validated_data["muid"] = register_helper.generate_muid( - validated_data["first_name"], validated_data.get('last_name', '') - ) password = validated_data.pop("password") hashed_password = make_password(password) validated_data["password"] = hashed_password diff --git a/db/hackathon.py b/db/hackathon.py index a7b07e4f..d7705367 100644 --- a/db/hackathon.py +++ b/db/hackathon.py @@ -2,6 +2,7 @@ from db.organization import Organization, District from db.user import User +from decouple import config as decouple_config # fmt: off # noinspection PyPep8 @@ -25,9 +26,9 @@ class Hackathon(models.Model): event_start = models.DateTimeField(blank=True, null=True) event_end = models.DateTimeField(blank=True, null=True) status = models.CharField(max_length=20, blank=True, null=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='hackathon_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='hackathon_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='hackathon_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='hackathon_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -41,9 +42,9 @@ class HackathonForm(models.Model): field_name = models.CharField(max_length=255) field_type = models.CharField(max_length=50) is_required = models.BooleanField(default=False) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='hackathon_form_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='hackathon_form_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='hackathon_form_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='hackathon_form_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -55,9 +56,9 @@ class HackathonOrganiserLink(models.Model): id = models.CharField(primary_key=True, max_length=36) organiser = models.ForeignKey(User, on_delete=models.CASCADE) hackathon = models.ForeignKey(Hackathon, on_delete=models.CASCADE) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='hackathon_organiser_link_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='hackathon_organiser_link_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='hackathon_organiser_link_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='hackathon_organiser_link_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -69,9 +70,9 @@ class HackathonUserSubmission(models.Model): id = models.CharField(primary_key=True, max_length=36) user = models.ForeignKey(User, on_delete=models.CASCADE) hackathon = models.ForeignKey(Hackathon, on_delete=models.CASCADE) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='hackathon_submission_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='hackathon_submission_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='hackathon_submission_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='hackathon_submission_created_by') created_at = models.DateTimeField(auto_now_add=True) data = models.JSONField(max_length=2000, blank=True, null=True) diff --git a/db/integrations.py b/db/integrations.py index 849d2649..0d49ec2d 100644 --- a/db/integrations.py +++ b/db/integrations.py @@ -1,5 +1,6 @@ import uuid +from decouple import config as decouple_config from django.db import models from db.user import User diff --git a/db/learning_circle.py b/db/learning_circle.py index bd3a9102..7332bfff 100644 --- a/db/learning_circle.py +++ b/db/learning_circle.py @@ -4,6 +4,7 @@ from db.task import InterestGroup, Organization from db.user import User +from decouple import config as decouple_config # fmt: off @@ -21,10 +22,10 @@ class LearningCircle(models.Model): meet_time = models.CharField(max_length=10, blank=True, null=True) day = models.CharField(max_length=20, blank=True, null=True) note = models.CharField(max_length=500, blank=True, null=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="learning_circle_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="learning_circle_created_by") created_at = models.DateTimeField(auto_now=True) @@ -58,10 +59,10 @@ class CircleMeetingLog(models.Model): attendees = models.CharField(max_length=216) agenda = models.CharField(max_length=2000) images = models.ImageField(max_length=200, upload_to='lc/meet-report') - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='circle_meeting_log_created_by') created_at = models.DateTimeField(auto_now=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='circle_meeting_log_updated_by') updated_at = models.DateTimeField(auto_now=True) diff --git a/db/managers/user_manager.py b/db/managers/user_manager.py index 9368ff21..1a2937e7 100644 --- a/db/managers/user_manager.py +++ b/db/managers/user_manager.py @@ -3,13 +3,11 @@ class ActiveUserManager(models.Manager): def get_queryset(self): - # This will return only the users where deleted_at, deleted_by, suspended_at, and suspended_by are NULL + # This will return only the users where suspended_at, and suspended_by are NULL return ( super() .get_queryset() .filter( - deleted_at__isnull=True, - deleted_by__isnull=True, suspended_at__isnull=True, suspended_by__isnull=True, ) diff --git a/db/notification.py b/db/notification.py index 5655dace..539ee1f6 100644 --- a/db/notification.py +++ b/db/notification.py @@ -1,5 +1,6 @@ import uuid +from decouple import config as decouple_config from django.db import models from db.user import User @@ -15,7 +16,7 @@ class Notification(models.Model): button = models.CharField(max_length=10, blank=True, null=True) url = models.CharField(max_length=100, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", related_name="created_notifications") + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="created_notifications") class Meta: managed = False diff --git a/db/organization.py b/db/organization.py index 2a3def18..f1eb7d52 100644 --- a/db/organization.py +++ b/db/organization.py @@ -1,20 +1,20 @@ import uuid +from decouple import config as decouple_config from django.db import models from .user import User - # fmt: off # noinspection PyPep8 class Country(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) name = models.CharField(max_length=75, null=False, unique=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='country_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='country_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -27,10 +27,10 @@ class State(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) name = models.CharField(max_length=75) country = models.ForeignKey(Country, on_delete=models.CASCADE, related_name='state_country') - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='state_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='state_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -43,10 +43,10 @@ class Zone(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) name = models.CharField(max_length=75) state = models.ForeignKey(State, on_delete=models.CASCADE, related_name='zone_state') - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='zone_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='zone_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -59,10 +59,10 @@ class District(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) name = models.CharField(max_length=75) zone = models.ForeignKey(Zone, on_delete=models.CASCADE, related_name="district_zone") - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='district_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='district_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -75,10 +75,10 @@ class OrgAffiliation(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4()) title = models.CharField(max_length=75) updated_by = models.ForeignKey( - User, on_delete=models.CASCADE, db_column='updated_by', related_name='org_affiliation_updated_by') + User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='org_affiliation_updated_by') updated_at = models.DateTimeField(auto_now=True) created_by = models.ForeignKey( - User, on_delete=models.CASCADE, db_column='created_by', related_name='org_affiliation_created_by') + User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='org_affiliation_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -93,10 +93,10 @@ class Organization(models.Model): org_type = models.CharField(max_length=25) affiliation = models.ForeignKey(OrgAffiliation, on_delete=models.CASCADE, blank=True, null=True, related_name='organization_affiliation') district = models.ForeignKey(District, on_delete=models.CASCADE, related_name='organization_district') - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='organization_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='organization_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -108,10 +108,10 @@ class Meta: class Department(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4()) title = models.CharField(max_length=100) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='department_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='department_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -124,10 +124,10 @@ class College(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4()) level = models.IntegerField(default=0) org = models.OneToOneField(Organization, on_delete=models.CASCADE, related_name='college_org', unique=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='college_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='college_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -140,10 +140,10 @@ class OrgDiscordLink(models.Model): id = models.CharField(primary_key=True, max_length=36) discord_id = models.CharField(unique=True, max_length=36) org = models.OneToOneField(Organization, on_delete=models.CASCADE, related_name='org_discord_link_org_id') - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='org_discord_link_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='org_discord_link_created_by') created_at = models.DateTimeField(auto_now_add=True) @@ -161,7 +161,7 @@ class UserOrganizationLink(models.Model): graduation_year = models.CharField(max_length=10, blank=True, null=True) verified = models.BooleanField() is_alumni = models.IntegerField(blank=True, null=True, default=False) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='user_organization_link_created_by') created_at = models.DateTimeField(auto_now_add=True) diff --git a/db/settings.py b/db/settings.py index ef660aad..e5dd11b5 100644 --- a/db/settings.py +++ b/db/settings.py @@ -1,3 +1,4 @@ +from decouple import config as decouple_config from django.db import models @@ -9,4 +10,4 @@ class SystemSetting(models.Model): class Meta: managed = False - db_table = 'system_setting' + db_table = "system_setting" diff --git a/db/task.py b/db/task.py index a8c524af..d9a5f818 100644 --- a/db/task.py +++ b/db/task.py @@ -1,10 +1,11 @@ import uuid +from decouple import config as decouple_config from django.db import models from db.organization import Organization -from .user import User +from .user import User # fmt: off # noinspection PyPep8 @@ -15,14 +16,14 @@ class Channel(models.Model): discord_id = models.CharField(max_length=36) updated_by = models.ForeignKey( User, - on_delete=models.CASCADE, + on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="channel_updated_by", ) updated_at = models.DateTimeField(auto_now=True) created_by = models.ForeignKey( User, - on_delete=models.CASCADE, + on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="channel_created_by", ) @@ -38,10 +39,10 @@ class InterestGroup(models.Model): name = models.CharField(max_length=75, unique=True) code = models.CharField(max_length=10, unique=True) icon = models.CharField(max_length=10) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="interest_group_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="interest_group_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -55,10 +56,10 @@ class Level(models.Model): level_order = models.IntegerField() name = models.CharField(max_length=36) karma = models.IntegerField() - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="level_created_by") created_at = models.DateTimeField(auto_now_add=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="level_updated_by") updated_at = models.DateTimeField(auto_now=True) @@ -71,10 +72,10 @@ class UserLvlLink(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user_lvl_link_user") level = models.ForeignKey(Level, on_delete=models.CASCADE, related_name="user_lvl_link_level") - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="user_lvl_link_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="user_lvl_link_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -86,10 +87,10 @@ class Meta: class TaskType(models.Model): id = models.CharField(primary_key=True, max_length=36) title = models.CharField(max_length=75) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="task_type_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="task_type_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -132,10 +133,10 @@ class Wallet(models.Model): karma = models.IntegerField(default=0) karma_last_updated_at = models.DateTimeField(blank=True, null=True, auto_now=True) coin = models.FloatField(default=0) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="wallet_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="wallet_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -154,16 +155,16 @@ class KarmaActivityLog(models.Model): lobby_message_id = models.CharField(max_length=36, blank=True, null=True) dm_message_id = models.CharField(max_length=36, blank=True, null=True) peer_approved = models.BooleanField(blank=True, null=True) - peer_approved_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="peer_approved_by", blank=True, + peer_approved_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="peer_approved_by", blank=True, null=True, related_name="karma_activity_log_peer_approved_by") appraiser_approved = models.BooleanField(blank=True, null=True) - appraiser_approved_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="appraiser_approved_by", + appraiser_approved_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="appraiser_approved_by", blank=True, null=True, related_name="karma_activity_log_appraiser_approved_by") - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="karma_activity_log_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="karma_activity_log_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -178,10 +179,10 @@ class MucoinActivityLog(models.Model): coin = models.FloatField() status = models.CharField(max_length=36) task = models.ForeignKey(TaskList, on_delete=models.CASCADE, related_name="mucoin_activity_log_task_list") - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="mucoin_activity_log_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="mucoin_activity_log_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -195,7 +196,7 @@ class MucoinInviteLog(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="mucoin_invite_log_user") email = models.CharField(max_length=200) invite_code = models.CharField(max_length=36) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="mucoin_invite_log_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -208,7 +209,7 @@ class UserIgLink(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_ig_link_user") ig = models.ForeignKey(InterestGroup, on_delete=models.CASCADE, related_name="user_ig_link_ig") - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="user_ig_link_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -228,10 +229,10 @@ class VoucherLog(models.Model): claimed = models.BooleanField() event = models.CharField(max_length=50, null=True) description = models.CharField(max_length=2000, null=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="voucher_log_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="voucher_log_created_by") created_at = models.DateTimeField(auto_now_add=True) @@ -244,10 +245,10 @@ class Events(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) name = models.CharField(max_length=75) description = models.CharField(max_length=200, null=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="updated_by", + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="updated_by", related_name="event_updated_by") updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_by", + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column="created_by", related_name="event_created_by") created_at = models.DateTimeField(auto_now_add=True) diff --git a/db/url_shortener.py b/db/url_shortener.py index 57aae37a..5b63f6ab 100644 --- a/db/url_shortener.py +++ b/db/url_shortener.py @@ -1,8 +1,8 @@ +from decouple import config as decouple_config from django.db import models from db.user import User - # fmt: off # noinspection PyPep8 @@ -12,10 +12,10 @@ class UrlShortener(models.Model): short_url = models.CharField(unique=True, max_length=100) long_url = models.CharField(max_length=500) count = models.IntegerField(blank=True, null=True, default=0) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='url_shortener_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='url_shortener_created_by') created_at = models.DateTimeField(auto_now_add=True) diff --git a/db/user.py b/db/user.py index b2a8d4dc..d3e1401d 100644 --- a/db/user.py +++ b/db/user.py @@ -1,21 +1,23 @@ import uuid +from decouple import config as decouple_config +from django.core.files.storage import FileSystemStorage from django.db import models + from .managers import user_manager -from django.core.files.storage import FileSystemStorage -from decouple import config as decouple_config + # fmt: off # noinspection PyPep8 class User(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) discord_id = models.CharField(unique=True, max_length=36, blank=True, null=True) - muid = models.CharField(unique=True, max_length=100) + muid = models.CharField(unique=True, max_length=100, null=True) first_name = models.CharField(max_length=75) last_name = models.CharField(max_length=75, blank=True, null=True) email = models.EmailField(unique=True, max_length=200) password = models.CharField(max_length=200, blank=True, null=True) - mobile = models.CharField(unique=True, max_length=15) + mobile = models.CharField(unique=True, max_length=15, error_messages={"unique" : "user with this mobile number already exists"}) gender = models.CharField(max_length=10, blank=True, null=True, choices=[("Male", "Male"), ("Female", "Female")]) dob = models.DateField(blank=True, null=True) admin = models.BooleanField(default=False) @@ -23,9 +25,7 @@ class User(models.Model): district = models.ForeignKey("District", on_delete=models.CASCADE, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) suspended_at = models.DateTimeField(blank=True, null=True) - suspended_by = models.ForeignKey("self", on_delete=models.CASCADE, blank=True, null=True, related_name="user_suspended_by_user", db_column="suspended_by") - deleted_at = models.DateTimeField(blank=True, null=True) - deleted_by = models.ForeignKey("self", on_delete=models.CASCADE, blank=True, null=True, related_name="user_deleted_by_user", db_column="deleted_by") + suspended_by = models.ForeignKey("self", on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), blank=True, null=True, related_name="user_suspended_by_user", db_column="suspended_by") objects = user_manager.ActiveUserManager() every = models.Manager() @@ -46,6 +46,17 @@ def profile_pic(self): path = f'user/profile/{self.id}.png' if fs.exists(path): return f"{decouple_config('BE_DOMAIN_NAME')}{fs.url(path)}" + + def save(self, *args, **kwargs): + full_name = f"{self.first_name}{self.last_name or ''}".replace(" ", "").lower()[:85] + self.muid = f"{full_name}@mulearn" + + counter = 0 + while User.objects.filter(muid=self.muid).exists(): + counter += 1 + self.muid = f"{full_name}-{counter}@mulearn" + + return super().save(*args, **kwargs) class UserReferralLink(models.Model): @@ -53,9 +64,9 @@ class UserReferralLink(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_referral_link_user') referral = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_referral_link_referral') is_coin = models.BooleanField(default=False) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_referral_link_updated_by', db_column='updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), related_name='user_referral_link_updated_by', db_column='updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_referral_link_created_by', db_column='created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), related_name='user_referral_link_created_by', db_column='created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -67,9 +78,9 @@ class Role(models.Model): id = models.CharField(primary_key=True, max_length=36) title = models.CharField(max_length=75) description = models.CharField(max_length=300, blank=True, null=True) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='role_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='updated_by', related_name='role_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='role_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='role_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -82,7 +93,7 @@ class UserRoleLink(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_role_link_user') role = models.ForeignKey(Role, on_delete=models.CASCADE) verified = models.BooleanField(default=False) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='user_role_link_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(decouple_config("SYSTEM_ADMIN_ID")), db_column='created_by', related_name='user_role_link_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -105,8 +116,8 @@ class Socials(models.Model): stackoverflow = models.CharField(max_length=60, blank=True, null=True) medium = models.CharField(max_length=60, blank=True, null=True) hackerrank = models.CharField(max_length=60, blank=True, null=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='socials_created_by') - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='socials_updated_by') + created_by = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='created_by', related_name='socials_created_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='updated_by', related_name='socials_updated_by') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(blank=True, null=True, auto_now=True) @@ -117,7 +128,7 @@ class Meta: class ForgotPassword(models.Model): id = models.CharField(primary_key=True, max_length=36) - user = models.ForeignKey(User, on_delete=models.CASCADE) + user = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID")))) expiry = models.DateTimeField() created_at = models.DateTimeField(auto_now_add=True) @@ -130,9 +141,9 @@ class UserSettings(models.Model): id = models.CharField(primary_key=True, max_length=36, default=uuid.uuid4) user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user_settings_user") is_public = models.BooleanField(default=False) - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='user_settings_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='updated_by', related_name='user_settings_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='user_settings_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='created_by', related_name='user_settings_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -144,9 +155,9 @@ class DynamicRole(models.Model): id = models.CharField(primary_key=True, max_length=36) type = models.CharField(max_length=50) role = models.ForeignKey(Role, on_delete=models.CASCADE, db_column='role', related_name='dynamic_role_role') - updated_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='updated_by', related_name='dynamic_role_updated_by') + updated_by = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='updated_by', related_name='dynamic_role_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey(User, on_delete=models.CASCADE, db_column='created_by', related_name='dynamic_role_created_by') + created_by = models.ForeignKey(User, on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='created_by', related_name='dynamic_role_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: @@ -158,9 +169,9 @@ class DynamicUser(models.Model): id = models.CharField(primary_key=True, max_length=36) type = models.CharField(max_length=50) user = models.ForeignKey('User', on_delete=models.CASCADE, related_name='dynamic_user_user') - updated_by = models.ForeignKey('User', on_delete=models.CASCADE, db_column='updated_by', related_name='dynamic_user_updated_by') + updated_by = models.ForeignKey('User', on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='updated_by', related_name='dynamic_user_updated_by') updated_at = models.DateTimeField(auto_now=True) - created_by = models.ForeignKey('User', on_delete=models.CASCADE, db_column='created_by', related_name='dynamic_user_created_by') + created_by = models.ForeignKey('User', on_delete=models.SET(models.SET(decouple_config("SYSTEM_ADMIN_ID"))), db_column='created_by', related_name='dynamic_user_created_by') created_at = models.DateTimeField(auto_now_add=True) class Meta: diff --git a/utils/utils.py b/utils/utils.py index 2849ea92..65168bdf 100644 --- a/utils/utils.py +++ b/utils/utils.py @@ -21,8 +21,12 @@ class CommonUtils: @staticmethod def get_paginated_queryset( - queryset: QuerySet, request, search_fields, sort_fields: dict = None, - is_pagination: bool = True) -> QuerySet: + queryset: QuerySet, + request, + search_fields, + sort_fields: dict = None, + is_pagination: bool = True, + ) -> QuerySet: if sort_fields is None: sort_fields = {} @@ -177,7 +181,8 @@ def read_excel_file(self, file_obj): def send_template_mail( - context: dict, subject: str, address: list[str], attachment: str = None): + context: dict, subject: str, address: list[str], attachment: str = None +): """ The function `send_user_mail` sends an email to a user with the provided user data, subject, and address.