@@ -154,20 +154,16 @@ class TargetSerializer(rest_framework.serializers.Serializer):
154
154
min_value = 0 ,
155
155
max_value = 100 ,
156
156
required = False ,
157
- allow_null = True ,
158
157
)
159
158
age_until = rest_framework .serializers .IntegerField (
160
159
min_value = 0 ,
161
160
max_value = 100 ,
162
161
required = False ,
163
- allow_null = True ,
164
162
)
165
163
country = rest_framework .serializers .CharField (
166
164
max_length = 2 ,
167
165
min_length = 2 ,
168
166
required = False ,
169
- allow_null = True ,
170
- allow_blank = True ,
171
167
)
172
168
categories = rest_framework .serializers .ListField (
173
169
child = rest_framework .serializers .CharField (
@@ -193,9 +189,8 @@ def validate(self, data):
193
189
194
190
country = data .get ('country' )
195
191
if country :
196
- country = country .strip ().upper ()
197
192
try :
198
- pycountry .countries .lookup (country )
193
+ pycountry .countries .lookup (country . strip (). upper () )
199
194
data ['country' ] = country
200
195
except LookupError :
201
196
raise rest_framework .serializers .ValidationError (
@@ -218,7 +213,7 @@ class PromoCreateSerializer(rest_framework.serializers.ModelSerializer):
218
213
django .core .validators .URLValidator (schemes = ['http' , 'https' ]),
219
214
],
220
215
)
221
- target = TargetSerializer (required = True )
216
+ target = TargetSerializer (required = True , allow_null = True )
222
217
promo_common = rest_framework .serializers .CharField (
223
218
min_length = 5 ,
224
219
max_length = 30 ,
@@ -446,3 +441,141 @@ def to_representation(self, instance):
446
441
data .pop ('promo_common' , None )
447
442
448
443
return data
444
+
445
+
446
+ class PromoDetailSerializer (rest_framework .serializers .ModelSerializer ):
447
+ promo_id = rest_framework .serializers .UUIDField (
448
+ source = 'id' ,
449
+ read_only = True ,
450
+ )
451
+ target = TargetSerializer (allow_null = True , required = False )
452
+ promo_unique = rest_framework .serializers .SerializerMethodField ()
453
+ company_name = rest_framework .serializers .CharField (
454
+ source = 'company.name' ,
455
+ read_only = True ,
456
+ )
457
+ like_count = rest_framework .serializers .SerializerMethodField ()
458
+ used_count = rest_framework .serializers .SerializerMethodField ()
459
+
460
+ class Meta :
461
+ model = business_models .Promo
462
+ fields = (
463
+ 'promo_id' ,
464
+ 'description' ,
465
+ 'image_url' ,
466
+ 'target' ,
467
+ 'max_count' ,
468
+ 'active_from' ,
469
+ 'active_until' ,
470
+ 'mode' ,
471
+ 'promo_common' ,
472
+ 'promo_unique' ,
473
+ 'company_name' ,
474
+ 'like_count' ,
475
+ 'used_count' ,
476
+ )
477
+
478
+ def get_promo_unique (self , obj ):
479
+ if obj .mode == business_models .Promo .MODE_UNIQUE :
480
+ return [code .code for code in obj .unique_codes .all ()]
481
+
482
+ return None
483
+
484
+ def update (self , instance , validated_data ):
485
+ target_data = validated_data .pop ('target' , None )
486
+ for attr , value in validated_data .items ():
487
+ setattr (instance , attr , value )
488
+
489
+ if target_data is not None :
490
+ instance .target = target_data
491
+
492
+ instance .save ()
493
+ return instance
494
+
495
+ def validate (self , data ):
496
+ instance = self .instance
497
+ full_data = {
498
+ 'mode' : instance .mode ,
499
+ 'promo_common' : instance .promo_common ,
500
+ 'promo_unique' : None ,
501
+ 'max_count' : instance .max_count ,
502
+ 'active_from' : instance .active_from ,
503
+ 'active_until' : instance .active_until ,
504
+ 'target' : instance .target if instance .target is not None else {},
505
+ }
506
+ full_data .update (data )
507
+ mode = full_data .get ('mode' )
508
+ promo_common = full_data .get ('promo_common' )
509
+ promo_unique = full_data .get ('promo_unique' )
510
+ max_count = full_data .get ('max_count' )
511
+
512
+ if mode == business_models .Promo .MODE_COMMON :
513
+ if not promo_common :
514
+ raise rest_framework .serializers .ValidationError (
515
+ {
516
+ 'promo_common' : (
517
+ 'This field is required for COMMON mode.'
518
+ ),
519
+ },
520
+ )
521
+
522
+ if promo_unique is not None :
523
+ raise rest_framework .serializers .ValidationError (
524
+ {
525
+ 'promo_unique' : (
526
+ 'This field is not allowed for COMMON mode.'
527
+ ),
528
+ },
529
+ )
530
+
531
+ if max_count < 0 or max_count > 100000000 :
532
+ raise rest_framework .serializers .ValidationError (
533
+ {'max_count' : 'Must be between 0 and 100,000,000.' },
534
+ )
535
+
536
+ elif mode == business_models .Promo .MODE_UNIQUE :
537
+ if not promo_unique :
538
+ raise rest_framework .serializers .ValidationError (
539
+ {
540
+ 'promo_unique' : (
541
+ 'This field is required for UNIQUE mode.'
542
+ ),
543
+ },
544
+ )
545
+
546
+ if promo_common is not None :
547
+ raise rest_framework .serializers .ValidationError (
548
+ {
549
+ 'promo_common' : (
550
+ 'This field is not allowed for UNIQUE mode.'
551
+ ),
552
+ },
553
+ )
554
+
555
+ if max_count != 1 :
556
+ raise rest_framework .serializers .ValidationError (
557
+ {'max_count' : 'Must be 1 for UNIQUE mode.' },
558
+ )
559
+ else :
560
+ raise rest_framework .serializers .ValidationError (
561
+ {'mode' : 'Invalid mode.' },
562
+ )
563
+
564
+ active_from = full_data .get ('active_from' )
565
+ active_until = full_data .get ('active_until' )
566
+
567
+ if active_from and active_until and active_from > active_until :
568
+ raise rest_framework .serializers .ValidationError (
569
+ {'active_until' : 'Must be after or equal to active_from.' },
570
+ )
571
+
572
+ return data
573
+
574
+ def get_like_count (self , obj ):
575
+ return 0
576
+
577
+ def get_used_count (self , obj ):
578
+ if obj .mode == business_models .Promo .MODE_UNIQUE :
579
+ return obj .unique_codes .filter (is_used = True ).count ()
580
+
581
+ return 0
0 commit comments