Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#639 Add Image model, update related code #646

Merged
merged 42 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d62ea41
profile image model added, profile model upd
Lvyshnevska Jun 13, 2024
c0fb468
completeness counter, image validation upd
Lvyshnevska Jun 13, 2024
9d9c34f
images urls changed
Lvyshnevska Jun 13, 2024
fb5305c
images views, serializer upd
Lvyshnevska Jun 13, 2024
ff0b83a
profile serializers upd
Lvyshnevska Jun 13, 2024
331c72a
typo fixed
Lvyshnevska Jun 13, 2024
1f0bd3e
queryset removed
Lvyshnevska Jun 13, 2024
a120789
fields added
Lvyshnevska Jun 13, 2024
d6d806f
migration error fixed
Lvyshnevska Jun 14, 2024
ac0be47
administration updated
Lvyshnevska Jun 18, 2024
60102d7
image type to context
Lvyshnevska Jun 18, 2024
7bc72e5
extension validation to model
Lvyshnevska Jun 18, 2024
0171851
tests add images
Lvyshnevska Jun 18, 2024
84ec34c
tests crud profile updated
Lvyshnevska Jun 18, 2024
fb62b4d
formatted by black
Lvyshnevska Jun 18, 2024
0556cb5
import fixed
Lvyshnevska Jun 18, 2024
1a8b2e4
extend schema upd
Lvyshnevska Jun 19, 2024
56595e0
search serializers, tests updated
Lvyshnevska Jun 19, 2024
e791900
profile instance to counter
Lvyshnevska Jun 19, 2024
b0d94c9
new members tests updated
Lvyshnevska Jun 19, 2024
ddc25e5
created_at field updated
Lvyshnevska Jun 19, 2024
ac30cf4
added lookup_field and lookup_url_kwarg for ImageDestroyAPIView
YanZhylavy Jun 19, 2024
6abe959
Added permission isAdminUser for ImageDestroyAPIView
YanZhylavy Jun 19, 2024
066209f
name fixed
Lvyshnevska Jun 19, 2024
b718f24
delete images tests
Lvyshnevska Jun 19, 2024
4421f9b
formatted
Lvyshnevska Jun 19, 2024
04797f9
check if deleted
Lvyshnevska Jun 19, 2024
5c66a13
Fixed tests for images
YanZhylavy Jun 19, 2024
a0118b6
permission to delete images
Lvyshnevska Jun 20, 2024
7bdd690
permission added, tests updated
Lvyshnevska Jun 20, 2024
6f870f2
profile images factory updated
Lvyshnevska Jun 20, 2024
bf15aaf
view updated
Lvyshnevska Jun 20, 2024
cb73ce1
move image files function updated
Lvyshnevska Jun 22, 2024
5e823ef
redundant variables removed
Lvyshnevska Jun 22, 2024
324e900
image type
Lvyshnevska Jun 22, 2024
69dc59d
content type to lower case
Lvyshnevska Jun 23, 2024
c52ef82
custom profile image field
Lvyshnevska Jun 23, 2024
7c31423
search tests updated
Lvyshnevska Jun 23, 2024
833b0b3
content type to lower case in factory
Lvyshnevska Jun 23, 2024
e6422e0
validation updated
Lvyshnevska Jun 25, 2024
f9707a0
redundant variable, return removed
Lvyshnevska Jun 25, 2024
49e6718
image path in tests updated
Lvyshnevska Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion BackEnd/administration/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@ class Meta:
person_position = "Test person position"
official_name = "Test official name"
startup_idea = "Test startup idea"
banner_image = "Test_banner_image"
is_deleted = False
19 changes: 19 additions & 0 deletions BackEnd/administration/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ class AdminCompanyDetailSerializer(serializers.ModelSerializer):
many=True, slug_field="name", read_only=True
)
regions = AdminRegionSerialaizer(many=True, read_only=True)
banner_image = serializers.ImageField(
source="banner.image_path", required=False
)
logo_image = serializers.ImageField(
source="logo.image_path", required=False
)
banner_approved_image = serializers.ImageField(
source="banner_approved.image_path", required=False
)
logo_approved_image = serializers.ImageField(
source="logo_approved.image_path", required=False
)

class Meta:
model = Profile
Expand All @@ -97,6 +109,13 @@ class Meta:
"product_info",
"address",
"startup_idea",
"banner",
"logo",
"banner_approved",
"logo_approved",
"banner_image",
"banner_approved_image",
"logo_image",
"logo_approved_image",
"is_deleted",
)
5 changes: 4 additions & 1 deletion BackEnd/administration/tests/test_admin_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ def test_get_profile_id_authenticated(self):
"product_info": "test product info",
"address": "Test Country, Test City, St. Test, 1",
"startup_idea": "Test startup idea",
"banner_image": "http://testserver/media/Test_banner_image",
"banner": None,
"logo": None,
"banner_approved": None,
"logo_approved": None,
"is_deleted": False,
}
self.assertEqual(data, response.json())
Expand Down
18 changes: 18 additions & 0 deletions BackEnd/images/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import factory.fuzzy

from .models import ProfileImage


class ProfileimageFactory(factory.django.DjangoModelFactory):
class Meta:
model = ProfileImage

uuid = factory.Faker("uuid4")
created_by = factory.SubFactory("authentication.factories.UserFactory")
image_type = factory.fuzzy.FuzzyChoice(
ProfileImage.IMAGE_TYPES, getter=lambda c: c[0]
)
content_type = "jpeg"
image_path = factory.django.ImageField(filename="test.jpeg")
is_approved = False
is_deleted = False
55 changes: 55 additions & 0 deletions BackEnd/images/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by Django 4.2.3 on 2024-06-12 12:22

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import images.models
import uuid


class Migration(migrations.Migration):
initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name="ProfileImage",
fields=[
(
"uuid",
models.UUIDField(
default=uuid.uuid4, primary_key=True, serialize=False
),
),
("created_at", models.DateField(auto_now_add=True)),
(
"image_type",
models.CharField(
choices=[("banner", "banner"), ("logo", "logo")], max_length=10
),
),
("content_type", models.CharField(blank=True, max_length=5)),
(
"image_path",
models.ImageField(
blank=True, upload_to=images.models.image_directory_path
),
),
("image_size", models.PositiveIntegerField(null=True)),
("hash_md5", models.CharField(blank=True, max_length=32)),
("is_approved", models.BooleanField(default=False)),
("is_deleted", models.BooleanField(default=False)),
(
"created_by",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="created_images",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 4.2.3 on 2024-06-19 12:51

import django.core.validators
from django.db import migrations, models
import images.models


class Migration(migrations.Migration):
dependencies = [
("images", "0001_initial"),
]

operations = [
migrations.AlterField(
model_name="profileimage",
name="created_at",
field=models.DateTimeField(auto_now_add=True),
),
migrations.AlterField(
model_name="profileimage",
name="image_path",
field=models.ImageField(
blank=True,
upload_to=images.models.image_directory_path,
validators=[
django.core.validators.FileExtensionValidator(
allowed_extensions=["jpeg", "png", "jpg"]
)
],
),
),
]
Empty file.
38 changes: 38 additions & 0 deletions BackEnd/images/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from uuid import uuid4
from django.db import models
from django.core.validators import FileExtensionValidator
from authentication.models import CustomUser


def image_directory_path(instance, filename):
return f"{instance.image_type}/{filename}"


class ProfileImage(models.Model):

BANNER = "banner"
LOGO = "logo"

IMAGE_TYPES = (
(BANNER, "banner"),
(LOGO, "logo"),
)

uuid = models.UUIDField(primary_key=True, default=uuid4)
created_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(
CustomUser, on_delete=models.CASCADE, related_name="created_images"
)
image_type = models.CharField(max_length=10, choices=IMAGE_TYPES)
content_type = models.CharField(max_length=5, blank=True)
image_path = models.ImageField(
upload_to=image_directory_path,
validators=[
FileExtensionValidator(allowed_extensions=["jpeg", "png", "jpg"])
],
blank=True,
)
image_size = models.PositiveIntegerField(null=True)
hash_md5 = models.CharField(max_length=32, blank=True)
is_approved = models.BooleanField(default=False)
is_deleted = models.BooleanField(default=False)
47 changes: 39 additions & 8 deletions BackEnd/images/serializers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
from rest_framework import serializers
from profiles.models import Profile
from images.models import ProfileImage

from validation.validate_image import (
validate_banner_size,
validate_logo_size,
)

class BannerSerializer(serializers.ModelSerializer):

class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ("banner_image",)
model = ProfileImage
fields = (
"uuid",
"image_type",
"image_path",
"created_by",
"content_type",
"image_size",
"hash_md5",
"is_approved",
"is_deleted",
"created_at",
)
read_only_fields = (
"uuid",
"created_at",
"created_by",
"image_type",
"content_type",
"image_size",
"hash_md5",
"is_approved",
"is_deleted",
)

def validate(self, value):
validator_function = {
ProfileImage.BANNER: validate_banner_size,
ProfileImage.LOGO: validate_logo_size,
}[self.context["view"].kwargs["image_type"]]

class LogoSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ("logo_image",)
validator_function(value.get("image_path"))

return value
Copy link

@ProDG ProDG Jun 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk about if/else here. When you'll add some third data type — chances you'll remember to add it here are pretty slim (especially if it will be OK to use validate_logo_size()).

validator_function = {
    ProfileImage.BANNER: validate_banner_size,
    ProfileImage.LOGO: validate_logo_size,
}[self.context["view"].kwargs["image_type"]
validator_function(value.get("image_path"))

return value

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading