|
1 | 1 | import re |
2 | 2 |
|
3 | 3 | import django.db.models |
4 | | -import django.shortcuts |
5 | 4 | import pycountry |
6 | 5 | import rest_framework.exceptions |
7 | 6 | import rest_framework.generics |
@@ -150,29 +149,7 @@ class CompanyPromoListView(rest_framework.generics.ListAPIView): |
150 | 149 | pagination_class = business.pagination.CustomLimitOffsetPagination |
151 | 150 |
|
152 | 151 | def get_queryset(self): |
153 | | - queryset = ( |
154 | | - business.models.Promo.objects.filter( |
155 | | - company=self.request.user, |
156 | | - ) |
157 | | - .select_related('company') |
158 | | - .prefetch_related('unique_codes') |
159 | | - .only( |
160 | | - 'id', |
161 | | - 'company', |
162 | | - 'description', |
163 | | - 'image_url', |
164 | | - 'target', |
165 | | - 'max_count', |
166 | | - 'active_from', |
167 | | - 'active_until', |
168 | | - 'mode', |
169 | | - 'promo_common', |
170 | | - 'created_at', |
171 | | - 'company__id', |
172 | | - 'company__name', |
173 | | - ) |
174 | | - ) |
175 | | - |
| 152 | + queryset = business.models.Promo.objects.for_company(self.request.user) |
176 | 153 | countries = [ |
177 | 154 | country.strip() |
178 | 155 | for group in self.request.query_params.getlist('country', []) |
@@ -298,113 +275,24 @@ def _validate_limit(self): |
298 | 275 | ) |
299 | 276 |
|
300 | 277 |
|
301 | | -class CompanyPromoDetailView(rest_framework.views.APIView): |
| 278 | +class CompanyPromoDetailView(rest_framework.generics.RetrieveUpdateAPIView): |
| 279 | + """ |
| 280 | + Retrieve (GET) and partially update (PATCH) detailed information |
| 281 | + about a company’s promo. |
| 282 | + """ |
| 283 | + |
| 284 | + http_method_names = ['get', 'patch', 'options', 'head'] |
| 285 | + |
| 286 | + serializer_class = business.serializers.PromoDetailSerializer |
| 287 | + |
302 | 288 | permission_classes = [ |
303 | 289 | rest_framework.permissions.IsAuthenticated, |
304 | 290 | business.permissions.IsCompanyUser, |
| 291 | + business.permissions.IsPromoOwner, |
305 | 292 | ] |
306 | 293 |
|
307 | 294 | lookup_field = 'id' |
308 | 295 |
|
309 | | - def get_queryset(self): |
310 | | - user = self.request.user |
311 | | - return ( |
312 | | - business.models.Promo.objects.filter(company=user) |
313 | | - .select_related('company') |
314 | | - .prefetch_related('unique_codes') |
315 | | - .select_related('company') |
316 | | - .prefetch_related('unique_codes') |
317 | | - .only( |
318 | | - 'id', |
319 | | - 'company', |
320 | | - 'description', |
321 | | - 'image_url', |
322 | | - 'target', |
323 | | - 'max_count', |
324 | | - 'active_from', |
325 | | - 'active_until', |
326 | | - 'mode', |
327 | | - 'promo_common', |
328 | | - 'created_at', |
329 | | - 'company__id', |
330 | | - 'company__name', |
331 | | - ) |
332 | | - ) |
333 | | - |
334 | | - def get(self, request, id): |
335 | | - try: |
336 | | - promo = business.models.Promo.objects.get( |
337 | | - id=id, |
338 | | - ) |
339 | | - except business.models.Promo.DoesNotExist: |
340 | | - raise rest_framework.exceptions.NotFound( |
341 | | - 'Promo not found,', |
342 | | - ) |
343 | | - |
344 | | - if promo.company != request.user: |
345 | | - return rest_framework.response.Response( |
346 | | - { |
347 | | - 'status': 'error', |
348 | | - 'message': ( |
349 | | - 'The promo code does not belong to this company.' |
350 | | - ), |
351 | | - }, |
352 | | - status=rest_framework.status.HTTP_403_FORBIDDEN, |
353 | | - ) |
354 | | - |
355 | | - serializer = business.serializers.PromoDetailSerializer( |
356 | | - promo, |
357 | | - ) |
358 | | - |
359 | | - return rest_framework.response.Response( |
360 | | - serializer.data, |
361 | | - status=rest_framework.status.HTTP_200_OK, |
362 | | - ) |
363 | | - |
364 | | - def patch(self, request, id, *args, **kwargs): |
365 | | - try: |
366 | | - promo = business.models.Promo.objects.get( |
367 | | - id=id, |
368 | | - ) |
369 | | - except business.models.Promo.DoesNotExist: |
370 | | - return rest_framework.response.Response( |
371 | | - { |
372 | | - 'status': 'error', |
373 | | - 'message': 'Promo code not found.', |
374 | | - }, |
375 | | - status=rest_framework.status.HTTP_404_NOT_FOUND, |
376 | | - ) |
377 | | - |
378 | | - if promo.company != request.user: |
379 | | - return rest_framework.response.Response( |
380 | | - { |
381 | | - 'status': 'error', |
382 | | - 'message': ('Promo code does not belong to this company.'), |
383 | | - }, |
384 | | - status=rest_framework.status.HTTP_403_FORBIDDEN, |
385 | | - ) |
386 | | - |
387 | | - serializer = business.serializers.PromoDetailSerializer( |
388 | | - promo, |
389 | | - data=request.data, |
390 | | - partial=True, |
391 | | - context={ |
392 | | - 'request': request, |
393 | | - }, |
394 | | - ) |
395 | | - |
396 | | - if not serializer.is_valid(): |
397 | | - return rest_framework.response.Response( |
398 | | - { |
399 | | - 'status': 'error', |
400 | | - 'message': 'Request data error.', |
401 | | - }, |
402 | | - status=rest_framework.status.HTTP_400_BAD_REQUEST, |
403 | | - ) |
404 | | - |
405 | | - serializer.save() |
406 | | - |
407 | | - return rest_framework.response.Response( |
408 | | - serializer.data, |
409 | | - status=rest_framework.status.HTTP_200_OK, |
410 | | - ) |
| 296 | + # Use an enriched base queryset without pre-filtering by company, |
| 297 | + # so that ownership mismatches raise 403 Forbidden (not 404 Not Found). |
| 298 | + queryset = business.models.Promo.objects.with_related() |
0 commit comments