From 084e3f56256b53266ad996249bdfda150b666ab4 Mon Sep 17 00:00:00 2001 From: Marsel Date: Fri, 25 Oct 2024 12:27:39 +0300 Subject: [PATCH 1/2] =?UTF-8?q?PRO-449:=20Remove=20organization=20user=20f?= =?UTF-8?q?ield=20=D0=A1=D1=82=D0=B0=D1=80=D0=BE=D0=B5=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=B8=D0=B7=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8F,?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D1=87=D0=B8=D0=B5=20=D1=81=D1=83=D1=89?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=B0=D0=B4=D0=B0=D0=BF=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=20=D0=BD=D0=BE=D0=B2=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/management/commands/__init__.py | 0 core/management/commands/migrate_education.py | 64 ------------------- .../commands/reverse_migrate_education.py | 51 --------------- log/migrated_users.json | 14 ---- users/admin.py | 6 +- users/filters.py | 3 +- .../0052_remove_customuser_organization.py | 17 +++++ users/models.py | 10 +-- users/serializers.py | 1 - 9 files changed, 22 insertions(+), 144 deletions(-) delete mode 100644 core/management/commands/__init__.py delete mode 100644 core/management/commands/migrate_education.py delete mode 100644 core/management/commands/reverse_migrate_education.py delete mode 100644 log/migrated_users.json create mode 100644 users/migrations/0052_remove_customuser_organization.py diff --git a/core/management/commands/__init__.py b/core/management/commands/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/core/management/commands/migrate_education.py b/core/management/commands/migrate_education.py deleted file mode 100644 index 24e178bc..00000000 --- a/core/management/commands/migrate_education.py +++ /dev/null @@ -1,64 +0,0 @@ -import json - -from django.db import transaction -from django.conf import settings -from django.core.management.base import BaseCommand -from django.contrib.auth import get_user_model - -from users.models import UserEducation - - -CustomUser = get_user_model() - - -class Command(BaseCommand): - """ - Use: python manage.py migrate_education. - """ - def handle(self, *args, **kwargs): - self.stdout.write("Start manual migration ...") - try: - total_user_migrate = migrate_organization_to_education() - self.stdout.write( - self.style.SUCCESS( - f"Manual migration complete, users migrated: {total_user_migrate}" - ) - ) - except Exception as e: - self.stderr.write( - self.style.ERROR(f"Migration failed: {str(e)}") - ) - - -@transaction.atomic -def migrate_organization_to_education() -> int: - """ - Migrate old field `organization` to new model `Education`. - Returns count migrated users. - Stored migrated info into `BASE_DIR / "log" / "migrated_users.json"` - """ - user_with_education_ids: list[int] = UserEducation.objects.values_list("user__id", flat=True) - users_with_organization_without_education = ( - CustomUser.objects - .exclude(organization=None) - .exclude(organization="") - .exclude(id__in=user_with_education_ids) - ) - UserEducation.objects.bulk_create([ - UserEducation( - user=user, - organization_name=user.organization, - ) - for user in users_with_organization_without_education - ]) - - data = [ - {"user_id": user.id, "user_organization_field": user.organization} - for user in users_with_organization_without_education - ] - - file_dump = settings.BASE_DIR / "log" / "migrated_users.json" - with open(file_dump, "w", encoding="utf-8") as file: - json.dump(data, file, indent=4, ensure_ascii=False) - - return users_with_organization_without_education.count() diff --git a/core/management/commands/reverse_migrate_education.py b/core/management/commands/reverse_migrate_education.py deleted file mode 100644 index 3791b1de..00000000 --- a/core/management/commands/reverse_migrate_education.py +++ /dev/null @@ -1,51 +0,0 @@ -from django.db import transaction -from django.contrib.auth import get_user_model -from django.core.management.base import BaseCommand, CommandParser - -from users.models import UserEducation - - -CustomUser = get_user_model() - - -class Command(BaseCommand): - """ - Use: python manage.py reverse_migrate_education. - """ - - def add_arguments(self, parser: CommandParser) -> None: - parser.add_argument( - "--confirm", - action="store_true", - help="Confirm delete Users educations from UserEducation model" - ) - - def handle(self, *args, **kwargs): - confirm = kwargs["confirm"] - self.stdout.write(self.style.WARNING( - "You are about to DELETE ALL INSTANCES in the UserEducation model.")) - - if not confirm: - answer = input("Type 'yes' to continue, or 'no' to cancel: ").lower() - if answer != "yes": - self.stdout.write(self.style.ERROR("Manual migrations canceled.")) - return - - self.stdout.write("Starting manual migrations...") - - try: - deleted_instances = delete_all_instances_usereducation() - self.stdout.write(self.style.SUCCESS("Manual migrations completed successfully.")) - self.stdout.write(self.style.SUCCESS(f"Deleted: {deleted_instances}")) - except Exception as e: - self.stderr.write(self.style.ERROR(f"Manual migrations failed: {str(e)}")) - - -@transaction.atomic -def delete_all_instances_usereducation() -> int: - """ - Destroy all UserEducation instances. - """ - count = UserEducation.objects.count() - UserEducation.objects.all().delete() - return count diff --git a/log/migrated_users.json b/log/migrated_users.json deleted file mode 100644 index 313931c6..00000000 --- a/log/migrated_users.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "user_id": 3, - "user_organization_field": "Учеба 1" - }, - { - "user_id": 4, - "user_organization_field": "Учеба 2" - }, - { - "user_id": 5, - "user_organization_field": "Учеба 3" - } -] \ No newline at end of file diff --git a/users/admin.py b/users/admin.py index 1fc6bd72..3fdeffbb 100644 --- a/users/admin.py +++ b/users/admin.py @@ -94,7 +94,6 @@ class CustomUserAdmin(admin.ModelAdmin): "status", "city", "region", - "organization", # TODO need to be removed in future. "speciality", "v2_speciality", "key_skills", @@ -264,6 +263,7 @@ def get_export_users_emails(self, users): "collaborations__project", "collaborations__project__industry", "skills__skill", + "education", ) ) little_mans = users.filter(birthday__lte=date_limit_18) @@ -290,7 +290,7 @@ def get_export_users_emails(self, users): baby.first_name + " " + baby.last_name, today.year - baby.birthday.year, ", ".join(interests), - baby.organization, + "; ".join(baby.education.values_list("organization_name", flat=True)), baby.v2_speciality if baby.v2_speciality else baby.speciality, baby.email, ] @@ -306,7 +306,7 @@ def get_export_users_emails(self, users): big_man.first_name + " " + big_man.last_name, today.year - big_man.birthday.year, ", ".join(industry_names), - big_man.organization, + "; ".join(big_man.education.values_list("organization_name", flat=True)), big_man.v2_speciality if big_man.v2_speciality else big_man.speciality, diff --git a/users/filters.py b/users/filters.py index f0fe2772..19855650 100644 --- a/users/filters.py +++ b/users/filters.py @@ -19,7 +19,7 @@ class UserFilter(filters.FilterSet): Parameters to filter by: first_name (str), last_name (str), patronymic (str), - city (str), region (str), organization (str), about_me__contains (str), + city (str), region (str), about_me__contains (str), useful_to_project__contains (str) Examples: @@ -121,7 +121,6 @@ class Meta: "patronymic", "city", "region", - "organization", # TODO need to be removed in future. "user_type", "speciality", ) diff --git a/users/migrations/0052_remove_customuser_organization.py b/users/migrations/0052_remove_customuser_organization.py new file mode 100644 index 00000000..1c55417e --- /dev/null +++ b/users/migrations/0052_remove_customuser_organization.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.11 on 2024-10-25 09:18 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("users", "0051_alter_usereducation_options_customuser_phone_number_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="customuser", + name="organization", + ), + ] diff --git a/users/models.py b/users/models.py index 4627b402..4cab5cb2 100644 --- a/users/models.py +++ b/users/models.py @@ -46,7 +46,6 @@ class CustomUser(AbstractUser): status: CharField instance notifies about the user's status. region: CharField instance the user's name region. city: CharField instance the user's name city. - organization: CharField instance the user's place of study or work. speciality: CharField instance the user's specialty. datetime_updated: A DateTimeField indicating date of update. datetime_created: A DateTimeField indicating date of creation. @@ -104,13 +103,6 @@ class CustomUser(AbstractUser): verbose_name="Номер телефона", help_text="Пример: +7 XXX XX-XX-XX | +7XXXXXXXXX | +7 (XXX) XX-XX-XX" ) - # TODO need to be removed in future `organization` -> `education`. - organization = models.CharField( - max_length=255, - null=True, - blank=True, - help_text="Устаревшее поле -> UserEducation", - ) v2_speciality = models.ForeignKey( on_delete=models.SET_NULL, null=True, @@ -179,7 +171,7 @@ def calculate_ordering_score(self) -> int: if self.city: score += 4 # TODO need to be removed in future. - if self.organization or self.education.all().exists(): + if self.education.all().exists(): score += 6 if self.speciality: score += 7 diff --git a/users/serializers.py b/users/serializers.py index 60e5abaf..52ab8b07 100644 --- a/users/serializers.py +++ b/users/serializers.py @@ -428,7 +428,6 @@ class Meta: "speciality", "v2_speciality", "v2_speciality_id", - "organization", # TODO need to be removed in future. "education", "work_experience", "user_languages", From 68b6153b3f7bdf6e9b1d1ae06547b325382d86da Mon Sep 17 00:00:00 2001 From: Alexey Kudelko Date: Fri, 1 Nov 2024 16:13:40 +0300 Subject: [PATCH 2/2] no useless error handeling in --- users/views.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/users/views.py b/users/views.py index 81600dbc..3d8f22f8 100644 --- a/users/views.py +++ b/users/views.py @@ -470,8 +470,6 @@ def post(self, request, *args, **kwargs): return Response( "User with given email does not exists!", status=status.HTTP_404_NOT_FOUND ) - except Exception: - return Response(status=status.HTTP_400_BAD_REQUEST) class ForceVerifyView(APIView): @@ -614,9 +612,7 @@ def get(self, request, *args, **kwargs) -> HttpResponse: data_preparer = UserCVDataPreparerV2(request.user.pk) user_cv_data: UserCVDataV2 = data_preparer.get_prepared_data() - html_string: str = render_to_string( - data_preparer.TEMPLATE_PATH, user_cv_data - ) + html_string: str = render_to_string(data_preparer.TEMPLATE_PATH, user_cv_data) binary_pdf_file: bytes | None = HTML(string=html_string).write_pdf() encoded_filename: str = urllib.parse.quote( @@ -635,6 +631,7 @@ class UserCVMailing(APIView): Full-fledged work `UserCVDownload`. The user can send a letter once per minute. """ + permission_classes = [IsAuthenticated] def get(self, request, *args, **kwargs):