Skip to content

Commit d32e0b8

Browse files
refactor(serializers): Move base serializers to core app
Relocate base serializers for users, promos, and comments from the `user` and `business` apps to the central `core` app. This change promotes code reuse and establishes a more logical and scalable project structure. - Moved `BaseUserSerializer`, `BaseUserPromoSerializer`, and `BaseCommentSerializer` to `core/serializers.py`. - Renamed `BasePromoSerializer` to `BaseCompanyPromoSerializer` for clarity. - Updated all dependent serializers in the `user` and `business` apps to inherit from the new centralized base classes in `core`.
1 parent c5926ca commit d32e0b8

File tree

3 files changed

+160
-159
lines changed

3 files changed

+160
-159
lines changed

promo_code/business/serializers.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,16 @@ def to_internal_value(self, data):
173173
return super().to_internal_value(data)
174174

175175

176-
class PromoCreateSerializer(core.serializers.BasePromoSerializer):
176+
class PromoCreateSerializer(core.serializers.BaseCompanyPromoSerializer):
177177
url = rest_framework.serializers.HyperlinkedIdentityField(
178178
view_name='api-business:promo-detail',
179179
lookup_field='id',
180180
)
181181

182-
class Meta(core.serializers.BasePromoSerializer.Meta):
183-
fields = ('url',) + core.serializers.BasePromoSerializer.Meta.fields
182+
class Meta(core.serializers.BaseCompanyPromoSerializer.Meta):
183+
fields = (
184+
'url',
185+
) + core.serializers.BaseCompanyPromoSerializer.Meta.fields
184186

185187
def create(self, validated_data):
186188
target_data = validated_data.pop('target')
@@ -225,7 +227,7 @@ def validate(self, attrs):
225227
return attrs
226228

227229

228-
class PromoDetailSerializer(core.serializers.BasePromoSerializer):
230+
class PromoDetailSerializer(core.serializers.BaseCompanyPromoSerializer):
229231
promo_id = rest_framework.serializers.UUIDField(
230232
source='id',
231233
read_only=True,
@@ -253,8 +255,8 @@ class PromoDetailSerializer(core.serializers.BasePromoSerializer):
253255

254256
promo_unique = rest_framework.serializers.SerializerMethodField()
255257

256-
class Meta(core.serializers.BasePromoSerializer.Meta):
257-
fields = core.serializers.BasePromoSerializer.Meta.fields + (
258+
class Meta(core.serializers.BaseCompanyPromoSerializer.Meta):
259+
fields = core.serializers.BaseCompanyPromoSerializer.Meta.fields + (
258260
'promo_id',
259261
'company_name',
260262
'like_count',

promo_code/core/serializers.py

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import django.contrib.auth.password_validation
12
import pycountry
23
import rest_framework.exceptions
34
import rest_framework.serializers
45

56
import business.constants
67
import business.models
8+
import user.constants
9+
import user.models
710

811

912
class BaseLimitOffsetPaginationSerializer(
@@ -96,7 +99,7 @@ def validate(self, data):
9699
return data
97100

98101

99-
class BasePromoSerializer(rest_framework.serializers.ModelSerializer):
102+
class BaseCompanyPromoSerializer(rest_framework.serializers.ModelSerializer):
100103
"""
101104
Base serializer for promo, containing validation and representation logic.
102105
"""
@@ -278,3 +281,140 @@ def to_representation(self, instance):
278281
data.pop('promo_unique', None)
279282

280283
return data
284+
285+
286+
class OtherFieldSerializer(rest_framework.serializers.Serializer):
287+
age = rest_framework.serializers.IntegerField(
288+
required=True,
289+
min_value=user.constants.AGE_MIN,
290+
max_value=user.constants.AGE_MAX,
291+
)
292+
country = CountryField(required=True)
293+
294+
295+
class BaseUserSerializer(rest_framework.serializers.ModelSerializer):
296+
password = rest_framework.serializers.CharField(
297+
write_only=True,
298+
required=True,
299+
validators=[django.contrib.auth.password_validation.validate_password],
300+
max_length=user.constants.PASSWORD_MAX_LENGTH,
301+
min_length=user.constants.PASSWORD_MIN_LENGTH,
302+
style={'input_type': 'password'},
303+
)
304+
name = rest_framework.serializers.CharField(
305+
required=True,
306+
min_length=user.constants.NAME_MIN_LENGTH,
307+
max_length=user.constants.NAME_MAX_LENGTH,
308+
)
309+
surname = rest_framework.serializers.CharField(
310+
required=True,
311+
min_length=user.constants.SURNAME_MIN_LENGTH,
312+
max_length=user.constants.SURNAME_MAX_LENGTH,
313+
)
314+
email = rest_framework.serializers.EmailField(
315+
required=True,
316+
min_length=user.constants.EMAIL_MIN_LENGTH,
317+
max_length=user.constants.EMAIL_MAX_LENGTH,
318+
)
319+
avatar_url = rest_framework.serializers.URLField(
320+
required=False,
321+
max_length=user.constants.AVATAR_URL_MAX_LENGTH,
322+
allow_null=True,
323+
)
324+
other = OtherFieldSerializer(required=True)
325+
326+
class Meta:
327+
model = user.models.User
328+
fields = (
329+
'name',
330+
'surname',
331+
'email',
332+
'password',
333+
'avatar_url',
334+
'other',
335+
)
336+
337+
338+
class BaseUserPromoSerializer(rest_framework.serializers.ModelSerializer):
339+
"""
340+
Base serializer for promos, containing common fields and methods.
341+
"""
342+
343+
promo_id = rest_framework.serializers.UUIDField(source='id')
344+
company_id = rest_framework.serializers.UUIDField(source='company.id')
345+
company_name = rest_framework.serializers.CharField(source='company.name')
346+
active = rest_framework.serializers.BooleanField(source='is_active')
347+
like_count = rest_framework.serializers.IntegerField(
348+
source='get_like_count',
349+
)
350+
comment_count = rest_framework.serializers.IntegerField(
351+
source='get_comment_count',
352+
)
353+
354+
is_liked_by_user = rest_framework.serializers.SerializerMethodField()
355+
is_activated_by_user = rest_framework.serializers.SerializerMethodField()
356+
357+
class Meta:
358+
model = business.models.Promo
359+
fields = (
360+
'promo_id',
361+
'company_id',
362+
'company_name',
363+
'description',
364+
'image_url',
365+
'active',
366+
'is_activated_by_user',
367+
'like_count',
368+
'comment_count',
369+
'is_liked_by_user',
370+
)
371+
read_only_fields = fields
372+
373+
def get_is_liked_by_user(self, obj: business.models.Promo) -> bool:
374+
"""
375+
Checks whether the current user has liked this promo.
376+
"""
377+
request = self.context.get('request')
378+
if (
379+
request
380+
and hasattr(request, 'user')
381+
and request.user.is_authenticated
382+
):
383+
return user.models.PromoLike.objects.filter(
384+
promo=obj,
385+
user=request.user,
386+
).exists()
387+
return False
388+
389+
def get_is_activated_by_user(self, obj: business.models.Promo) -> bool:
390+
"""
391+
Checks whether the current user has activated this promo code.
392+
"""
393+
request = self.context.get('request')
394+
395+
if not (
396+
request
397+
and hasattr(request, 'user')
398+
and request.user.is_authenticated
399+
):
400+
return False
401+
402+
return user.models.PromoActivationHistory.objects.filter(
403+
promo=obj,
404+
user=request.user,
405+
).exists()
406+
407+
408+
class BaseCommentSerializer(rest_framework.serializers.ModelSerializer):
409+
"""
410+
Base serializer for promo comments.
411+
"""
412+
413+
text = rest_framework.serializers.CharField(
414+
min_length=user.constants.COMMENT_TEXT_MIN_LENGTH,
415+
max_length=user.constants.COMMENT_TEXT_MAX_LENGTH,
416+
)
417+
418+
class Meta:
419+
model = user.models.PromoComment
420+
fields = ('text',)

0 commit comments

Comments
 (0)