Skip to content

Commit fa59d7c

Browse files
refactor: Combine promo list and create endpoints
Replaced separate views for listing and creating company promos with a single CompanyPromoListCreateView based on ListCreateAPIView. This simplifies the API by handling GET and POST requests for promos at a single URL endpoint (`api/business/promo`). - Uses get_serializer_class for appropriate request methods. - Moved query param validation into the list method. - Updated urls.py to point to the new combined view. - Remove redundant imports in serializers.
1 parent 669cc9f commit fa59d7c

File tree

3 files changed

+50
-54
lines changed

3 files changed

+50
-54
lines changed

promo_code/business/serializers.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import business.constants
1414
import business.models
15-
import business.models as business_models
1615
import business.utils.auth
1716
import business.utils.tokens
1817
import business.validators
@@ -46,12 +45,12 @@ class CompanySignUpSerializer(rest_framework.serializers.ModelSerializer):
4645
)
4746

4847
class Meta:
49-
model = business_models.Company
48+
model = business.models.Company
5049
fields = ('id', 'name', 'email', 'password')
5150

5251
@django.db.transaction.atomic
5352
def create(self, validated_data):
54-
company = business_models.Company.objects.create_company(
53+
company = business.models.Company.objects.create_company(
5554
**validated_data,
5655
)
5756

@@ -76,8 +75,8 @@ def validate(self, attrs):
7675
)
7776

7877
try:
79-
company = business_models.Company.objects.get(email=email)
80-
except business_models.Company.DoesNotExist:
78+
company = business.models.Company.objects.get(email=email)
79+
except business.models.Company.DoesNotExist:
8180
raise rest_framework.serializers.ValidationError(
8281
'Invalid credentials.',
8382
)
@@ -227,7 +226,7 @@ class PromoCreateSerializer(rest_framework.serializers.ModelSerializer):
227226
)
228227

229228
class Meta:
230-
model = business_models.Promo
229+
model = business.models.Promo
231230
fields = (
232231
'url',
233232
'description',
@@ -251,7 +250,7 @@ def create(self, validated_data):
251250
promo_common = validated_data.pop('promo_common', None)
252251
promo_unique = validated_data.pop('promo_unique', None)
253252

254-
return business_models.Promo.objects.create_promo(
253+
return business.models.Promo.objects.create_promo(
255254
user=self.context['request'].user,
256255
target_data=target_data,
257256
promo_common=promo_common,
@@ -418,7 +417,7 @@ class PromoReadOnlySerializer(rest_framework.serializers.ModelSerializer):
418417
)
419418

420419
class Meta:
421-
model = business_models.Promo
420+
model = business.models.Promo
422421
fields = (
423422
'promo_id',
424423
'company_id',
@@ -484,7 +483,7 @@ class PromoDetailSerializer(rest_framework.serializers.ModelSerializer):
484483
)
485484

486485
class Meta:
487-
model = business_models.Promo
486+
model = business.models.Promo
488487
fields = (
489488
'promo_id',
490489
'description',

promo_code/business/urls.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,9 @@
2222
name='company-token-refresh',
2323
),
2424
django.urls.path(
25-
'promo/create',
26-
business.views.PromoCreateView.as_view(),
27-
name='promo-create',
28-
),
29-
django.urls.path(
30-
'promo/list',
31-
business.views.CompanyPromoListView.as_view(),
32-
name='company-promo-list',
25+
'promo',
26+
business.views.CompanyPromoListCreateView.as_view(),
27+
name='promo-list-create',
3328
),
3429
django.urls.path(
3530
'promo/<uuid:id>',

promo_code/business/views.py

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -62,73 +62,75 @@ class CompanyTokenRefreshView(rest_framework_simplejwt.views.TokenRefreshView):
6262
serializer_class = business.serializers.CompanyTokenRefreshSerializer
6363

6464

65-
class PromoCreateView(rest_framework.generics.CreateAPIView):
65+
class CompanyPromoListCreateView(rest_framework.generics.ListCreateAPIView):
6666
"""
67-
View for creating a new promo (POST).
67+
View for listing (GET) and creating (POST) company promos.
6868
"""
6969

7070
permission_classes = [
7171
rest_framework.permissions.IsAuthenticated,
7272
business.permissions.IsCompanyUser,
7373
]
74-
serializer_class = business.serializers.PromoCreateSerializer
75-
76-
def perform_create(self, serializer):
77-
return serializer.save()
78-
79-
def create(self, request, *args, **kwargs):
80-
serializer = self.get_serializer(data=request.data)
81-
82-
serializer.is_valid(raise_exception=True)
83-
84-
instance = self.perform_create(serializer)
85-
86-
headers = self.get_success_headers(serializer.data)
87-
88-
response_data = {'id': str(instance.id)}
89-
90-
return rest_framework.response.Response(
91-
response_data,
92-
status=rest_framework.status.HTTP_201_CREATED,
93-
headers=headers,
94-
)
74+
# Pagination is only needed for GET (listing)
75+
pagination_class = business.pagination.CustomLimitOffsetPagination
9576

77+
_validated_query_params = {}
9678

97-
class CompanyPromoListView(rest_framework.generics.ListAPIView):
98-
permission_classes = [
99-
rest_framework.permissions.IsAuthenticated,
100-
business.permissions.IsCompanyUser,
101-
]
102-
serializer_class = business.serializers.PromoReadOnlySerializer
103-
pagination_class = business.pagination.CustomLimitOffsetPagination
79+
def get_serializer_class(self):
80+
if self.request.method == 'POST':
81+
return business.serializers.PromoCreateSerializer
10482

105-
def initial(self, request, *args, **kwargs):
106-
super().initial(request, *args, **kwargs)
83+
return business.serializers.PromoReadOnlySerializer
10784

108-
serializer = business.serializers.PromoListQuerySerializer(
85+
def list(self, request, *args, **kwargs):
86+
query_serializer = business.serializers.PromoListQuerySerializer(
10987
data=request.query_params,
11088
)
111-
serializer.is_valid(raise_exception=True)
112-
request.validated_query_params = serializer.validated_data
89+
query_serializer.is_valid(raise_exception=True)
90+
self._validated_query_params = query_serializer.validated_data
91+
92+
return super().list(request, *args, **kwargs)
11393

11494
def get_queryset(self):
115-
params = self.request.validated_query_params
95+
params = self._validated_query_params
11696
countries = [c.upper() for c in params.get('countries', [])]
11797
sort_by = params.get('sort_by')
11898

11999
queryset = business.models.Promo.objects.for_company(self.request.user)
120100

121101
if countries:
102+
# Using a regular expression for case-insensitive searching
122103
regex_pattern = r'(' + '|'.join(map(re.escape, countries)) + ')'
104+
country_filter = django.db.models.Q(
105+
target__country__iregex=regex_pattern,
106+
)
107+
108+
# Include promos where the country is not specified
123109
queryset = queryset.filter(
124-
django.db.models.Q(target__country__iregex=regex_pattern)
110+
country_filter
125111
| django.db.models.Q(target__country__isnull=True),
126112
)
127113

128114
ordering = f'-{sort_by}' if sort_by else '-created_at'
129115

130116
return queryset.order_by(ordering)
131117

118+
def perform_create(self, serializer):
119+
return serializer.save()
120+
121+
def create(self, request, *args, **kwargs):
122+
serializer = self.get_serializer(data=request.data)
123+
serializer.is_valid(raise_exception=True)
124+
instance = self.perform_create(serializer)
125+
headers = self.get_success_headers(serializer.data)
126+
response_data = {'id': str(instance.id)}
127+
128+
return rest_framework.response.Response(
129+
response_data,
130+
status=rest_framework.status.HTTP_201_CREATED,
131+
headers=headers,
132+
)
133+
132134

133135
class CompanyPromoDetailView(rest_framework.generics.RetrieveUpdateAPIView):
134136
"""

0 commit comments

Comments
 (0)