From 73ed563f9ee1c6909de57e9983d8d28822a9f054 Mon Sep 17 00:00:00 2001 From: Suhani97 Date: Wed, 1 Dec 2021 15:07:00 +0530 Subject: [PATCH 1/2] profile_image_updated --- custom_auth/admin.py | 3 +- custom_auth/migrations/0001_initial.py | 11 ++++- .../migrations/0002_auto_20211130_2023.py | 24 ++++++++++ custom_auth/models.py | 20 ++++---- custom_auth/serializers.py | 21 +++++---- custom_auth/tests/test_views.py | 46 ++++++++++--------- custom_auth/views.py | 30 +++++++++++- udyam_backend/settings.py | 4 ++ udyam_backend/urls.py | 2 + 9 files changed, 118 insertions(+), 43 deletions(-) create mode 100644 custom_auth/migrations/0002_auto_20211130_2023.py diff --git a/custom_auth/admin.py b/custom_auth/admin.py index f269e65..1d2c65a 100644 --- a/custom_auth/admin.py +++ b/custom_auth/admin.py @@ -1,6 +1,7 @@ from django.contrib import admin # Register your models here. -from custom_auth.models import UserAccount +from custom_auth.models import UserAccount, ProfileImages admin.site.register(UserAccount) +admin.site.register(ProfileImages) diff --git a/custom_auth/migrations/0001_initial.py b/custom_auth/migrations/0001_initial.py index b29a125..3966bb6 100644 --- a/custom_auth/migrations/0001_initial.py +++ b/custom_auth/migrations/0001_initial.py @@ -1,6 +1,7 @@ -# Generated by Django 3.2.7 on 2021-11-15 17:29 +# Generated by Django 3.2.7 on 2021-11-28 08:55 from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -11,6 +12,13 @@ class Migration(migrations.Migration): ] operations = [ + migrations.CreateModel( + name='ProfileImages', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image', models.ImageField(blank=True, default='udyamLogo.png', upload_to='images')), + ], + ), migrations.CreateModel( name='UserAccount', fields=[ @@ -28,6 +36,7 @@ class Migration(migrations.Migration): ('user_referral_code', models.CharField(max_length=10)), ('referral_code', models.CharField(blank=True, max_length=10, null=True)), ('referral_count', models.IntegerField(default=0)), + ('profile_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='custom_auth.profileimages')), ], options={ 'abstract': False, diff --git a/custom_auth/migrations/0002_auto_20211130_2023.py b/custom_auth/migrations/0002_auto_20211130_2023.py new file mode 100644 index 0000000..db8ee75 --- /dev/null +++ b/custom_auth/migrations/0002_auto_20211130_2023.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.8 on 2021-11-30 14:53 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('custom_auth', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='useraccount', + name='profile_image', + ), + migrations.AddField( + model_name='profileimages', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/custom_auth/models.py b/custom_auth/models.py index 7448314..597750e 100644 --- a/custom_auth/models.py +++ b/custom_auth/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager +from django.db.models.deletion import CASCADE class AccountManager(BaseUserManager): @@ -28,8 +29,7 @@ def create_superuser(self, email, password): class UserAccount(AbstractBaseUser): email = models.EmailField(verbose_name="email", max_length=60, unique=True) - date_joined = models.DateTimeField(verbose_name="date joined", - auto_now_add=True) + date_joined = models.DateTimeField(verbose_name="date joined", auto_now_add=True) is_admin = models.BooleanField(default=False) is_active = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) @@ -42,15 +42,10 @@ class UserAccount(AbstractBaseUser): ("THREE", "3rd year"), ("FOUR", "4th year"), ) - year = models.CharField(max_length=20, - choices=YEARS, - blank=False, - null=False) + year = models.CharField(max_length=20, choices=YEARS, blank=False, null=False) # referral codes - user_referral_code = models.CharField(max_length=10, - blank=False, - null=False) + user_referral_code = models.CharField(max_length=10, blank=False, null=False) referral_code = models.CharField(max_length=10, blank=True, null=True) referral_count = models.IntegerField(default=0) @@ -69,3 +64,10 @@ def has_perm(self, perm, obj=None): # Does this user have permission to view this app? def has_module_perms(self, app_label): return True + + +class ProfileImages(models.Model): + user = models.ForeignKey( + UserAccount, on_delete=models.CASCADE, null=True, blank=True + ) + image = models.ImageField(default="udyamLogo.png", upload_to="images", blank=True) diff --git a/custom_auth/serializers.py b/custom_auth/serializers.py index 42830d6..d8529f5 100644 --- a/custom_auth/serializers.py +++ b/custom_auth/serializers.py @@ -8,7 +8,7 @@ from rest_framework.exceptions import AuthenticationFailed from rest_framework.validators import UniqueValidator -from .models import UserAccount +from .models import UserAccount, ProfileImages class LoginSerializer(serializers.ModelSerializer): @@ -65,15 +65,15 @@ class TokenSerializer(serializers.Serializer): class RegisterSerializer(serializers.Serializer): # TODO: Implement register functionality email = serializers.EmailField( - required=True, - validators=[UniqueValidator(queryset=UserAccount.objects.all())]) + required=True, validators=[UniqueValidator(queryset=UserAccount.objects.all())] + ) password = serializers.CharField(write_only=True, required=True) name = serializers.CharField(required=True) year = serializers.CharField(required=True) college_name = serializers.CharField(required=True) - referral_code = serializers.CharField(required=False, - allow_blank=True, - allow_null=True) + referral_code = serializers.CharField( + required=False, allow_blank=True, allow_null=True + ) class Meta: model = UserAccount @@ -89,7 +89,7 @@ def create(self, validated_data): user.college_name = validated_data["college_name"] user.referral_code = validated_data["referral_code"] name = (user.name).replace(" ", "").lower() - user.user_referral_code = name[:min(len(user.name), 5)] + user.user_referral_code = name[: min(len(user.name), 5)] user.user_referral_code += str(random.randint(10001, 99999)) user.save() return user @@ -100,15 +100,20 @@ class UserSerializer(serializers.Serializer): gender = serializers.CharField(required=True) year = serializers.CharField(required=True) college_name = serializers.CharField(required=True) + profile_image = serializers.ImageField(required=False) class Meta: model = UserAccount fields = "__all__" def create(self, validated_data): - user = UserAccount.objects.get(email=validated_data["email"], ) + user = UserAccount.objects.get( + email=validated_data["email"], + ) user.name = validated_data["name"] user.year = validated_data["year"] user.college_name = validated_data["college_name"] + user.profile_image = validated_data["profile_image"] + user.save() return user diff --git a/custom_auth/tests/test_views.py b/custom_auth/tests/test_views.py index 3b248fd..9c9153a 100644 --- a/custom_auth/tests/test_views.py +++ b/custom_auth/tests/test_views.py @@ -16,11 +16,11 @@ def setUp(self): "email": "test_user1@example.com", "password": "test_password1", } - self.test_user1 = UserAccount.objects.create_user( - **self.credentials_user1) + self.test_user1 = UserAccount.objects.create_user(**self.credentials_user1) self.test_user1.name = "test_user1_name" self.test_user1.year = "2nd year" self.test_user1.college_name = "IIT BHU" + # self.test_user1.profile_image = "udyamLogo.png" self.test_user1.save() self.credentials_user2 = { @@ -30,6 +30,7 @@ def setUp(self): "year": "2nd year", "college_name": "IIT BHU", "referral_code": "", + # "profile_image": "udyamLogo.png", } self.auth_token = Token.objects.get_or_create(user=self.test_user1) @@ -40,24 +41,25 @@ def setUp(self): self.logout_url = reverse("logout") self.update_url = reverse("update") self.register_url = reverse("register") - self.activate_account_url1 = reverse("activate-account", - args=[self.uidb64, self.token]) + self.activate_account_url1 = reverse( + "activate-account", args=[self.uidb64, self.token] + ) self.activate_account_url2 = reverse( - "activate-account", args=["some-uidb64", "some-token"]) + "activate-account", args=["some-uidb64", "some-token"] + ) self.password_reset_email_url = reverse("password-reset-email") self.password_reset_confirm_url1 = reverse( - "password-reset-confirm", args=[self.uidb64, self.token]) + "password-reset-confirm", args=[self.uidb64, self.token] + ) self.password_reset_confirm_url2 = reverse( - "password-reset-confirm", args=["some-uidb64", "some-token"]) + "password-reset-confirm", args=["some-uidb64", "some-token"] + ) # Invalid user login def test_login_view_401(self): response = self.client.post( self.login_url, - { - "email": "test_user1@example.com", - "password": "test_password1" - }, + {"email": "test_user1@example.com", "password": "test_password1"}, ) self.assertEqual(response.status_code, 401) @@ -88,6 +90,7 @@ def test_register_view_POST_same_credentials(self): "year": "2nd year", "college_name": "IIT BHU", "referral_code": "", + # "profile_image": "udyamLogo.png", }, ) self.assertEqual(response.status_code, 409) @@ -105,20 +108,23 @@ def test_activate_account_view_GET_401(self): # Password reset: email is valid and user is active def test_password_reset_email_view_POST_200(self): self.client.get(self.activate_account_url1) - response = self.client.post(self.password_reset_email_url, - {"email": "test_user1@example.com"}) + response = self.client.post( + self.password_reset_email_url, {"email": "test_user1@example.com"} + ) self.assertEqual(response.status_code, 200) # Password reset: email is valid and user is not active def test_password_reset_email_view_POST_401(self): - response = self.client.post(self.password_reset_email_url, - {"email": "test_user1@example.com"}) + response = self.client.post( + self.password_reset_email_url, {"email": "test_user1@example.com"} + ) self.assertEqual(response.status_code, 401) # Password reset: email is invalid def test_password_reset_email_view_POST_400(self): - response = self.client.post(self.password_reset_email_url, - {"email": "test_us@example.com"}) + response = self.client.post( + self.password_reset_email_url, {"email": "test_us@example.com"} + ) self.assertEqual(response.status_code, 400) # Valid arguments (uidb64, token) @@ -135,11 +141,7 @@ def test_password_token_check_view_GET_401(self): def test_new_password_successfully_set(self): response = self.client.patch( reverse("password-reset-complete"), - { - "password": "NewPassword123", - "token": self.token, - "uidb64": self.uidb64 - }, + {"password": "NewPassword123", "token": self.token, "uidb64": self.uidb64}, ) self.assertEqual(response.status_code, 200) diff --git a/custom_auth/views.py b/custom_auth/views.py index 19b1e1b..583e641 100644 --- a/custom_auth/views.py +++ b/custom_auth/views.py @@ -8,7 +8,7 @@ LoginSerializer, UserSerializer, ) -from .models import UserAccount +from .models import UserAccount, ProfileImages from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.utils.encoding import ( smart_str, @@ -173,15 +173,25 @@ class UserUpdateView(generics.GenericAPIView): def get(self, request): try: user = request.user + current_site = get_current_site(request=request).domain + try: + image = str(ProfileImages.objects.get(user=user).image) + except: + image = "udyamLogo.png" content = { "name": user.name, "email": user.email, "college_name": user.college_name, "year": user.year, "referral_code": user.user_referral_code, + "profile_image": "http://" + + current_site + + "/images/" + + image, } return Response(content, status=status.HTTP_200_OK) - except serializers.get_error_detail: + except Exception as e: + print(e) return Response( {"error": "An error occurred!"}, status=status.HTTP_403_FORBIDDEN ) @@ -199,6 +209,12 @@ def post(self, request): user.update( college_name=request.data["college_name"], ) + if "profile_image" in request.data: + ProfileImages.objects.get(user=user).delete() + ProfileImages.objects.create( + user=user, + image=request.data["profile_image"], + ) return Response( {"message": "Updated successfully!"}, status=status.HTTP_200_OK ) @@ -218,6 +234,16 @@ def post(self, request): user = check(request.data) if user is None: user = serializer.save() + if "profile_image" in request.data: + ProfileImages.objects.create( + user=user, + image=request.data["profile_image"], + ) + else: + ProfileImages.objects.create( + user=user, + image="udyamLogo.png", + ) create_auth_token(user=user) uidb64 = urlsafe_base64_encode(smart_bytes(user.id)) token = PasswordResetTokenGenerator().make_token(user) diff --git a/udyam_backend/settings.py b/udyam_backend/settings.py index 8f14c23..bfda8e5 100644 --- a/udyam_backend/settings.py +++ b/udyam_backend/settings.py @@ -40,6 +40,7 @@ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + "django_cleanup.apps.CleanupConfig", "rest_framework", "rest_framework.authtoken", "drf_yasg", @@ -141,7 +142,10 @@ # https://docs.djangoproject.com/en/3.0/howto/static-files/ STATIC_URL = "/static/" +MEDIA_URL = "/images/" + STATIC_ROOT = os.path.join(BASE_DIR, "static/") +MEDIA_ROOT = os.path.join(BASE_DIR, "static/images") EMAIL_USE_TLS = True EMAIL_HOST = "smtp.gmail.com" diff --git a/udyam_backend/urls.py b/udyam_backend/urls.py index 79ec722..ad1bf39 100644 --- a/udyam_backend/urls.py +++ b/udyam_backend/urls.py @@ -40,3 +40,5 @@ schema_view.with_ui("redoc", cache_timeout=0), name="schema-redoc"), ] + +urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) From 0a5715745656d4b536663161b573cd7d8e814b7d Mon Sep 17 00:00:00 2001 From: Suhani97 Date: Wed, 1 Dec 2021 15:13:41 +0530 Subject: [PATCH 2/2] module_added --- requirements/common.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements/common.txt b/requirements/common.txt index 90233ea..2325b3a 100644 --- a/requirements/common.txt +++ b/requirements/common.txt @@ -4,3 +4,5 @@ django-cors-headers==3.10.0 djangorestframework==3.12.4 pytz==2021.3 sqlparse==0.4.2 +pillow==8.4.0 +django_cleanup==5.2.0