17.1. API REST

17.1.1. Product List

File shop/api.py:

>>> 
... from http import HTTPStatus
... from django.http import JsonResponse
... from django.views import View
... from shop.models import Product
...
...
... class ProductListAPI(View):
...     http_method_names = ['get']
...
...     def get(self, request):
...         products = Product.objects.all().values()
...         response = list(products)
...         return JsonResponse(status=HTTPStatus.OK, data=response, safe=False)

File myproject/urls.py:

>>> path('api/v1/products/', ProductListAPI.as_view(), name='product-list-api'),

17.1.2. Product Get

File shop/api.py:

>>> 
... from http import HTTPStatus
... from django.http import JsonResponse
... from django.views import View
... from shop.models import Product
...
...
... class ProductGetAPI(View):
...     http_method_names = ['get']
...
...     def get(self, request, pk):
...         try:
...             product = Product.objects.get(pk=pk)
...         except Product.DoesNotExist:
...             response = {'reason': 'Not found', 'detail': 'Product does not exists'}
...             return JsonResponse(status=HTTPStatus.NOT_FOUND, data=response, safe=False)
...         else:
...             response = vars(product)
...             response.pop('_state')
...             return JsonResponse(status=HTTPStatus.OK, data=response)

File myproject/urls.py:

>>> path('api/v1/product/<int:pk>/', ProductDetailAPI.as_view(), name='product-detail-api'),

17.1.3. Product Create

File shop/api.py:

>>> 
... import json
... from decimal import Decimal
... from http import HTTPStatus
... from django.core.exceptions import ValidationError
... from django.http import JsonResponse
... from django.views import View
... from django.views.decorators.csrf import csrf_exempt
... from shop.models import Product
...
...
... class ProductCreateAPI(View):
...     http_method_names = ['post']
...
...     @csrf_exempt
...     def dispatch(self, request, *args, **kwargs):
...         return super().dispatch(request, *args, **kwargs)
...
...     def post(self, request, *args, **kwargs):
...         data = json.loads(request.body.decode('utf-8'))
...         if Product.objects.filter(ean13=data['ean13']).exists():
...             response = {'reason': 'Already Reported', 'detail': 'Product already exists'}
...             return JsonResponse(status=HTTPStatus.ALREADY_REPORTED, data=response, safe=False)
...         try:
...             Product.objects.create(
...                 ean13=data['ean13'],
...                 name=data['name'],
...                 price=Decimal(str(data['price'])))
...         except ValidationError as error:
...             response = {'reason': 'Bad request', 'detail': str(error)}
...             return JsonResponse(status=HTTPStatus.UNPROCESSABLE_ENTITY, data=response, safe=False)
...         except Exception as error:
...             response = {'reason': 'Bad request', 'detail': str(error)}
...             return JsonResponse(status=HTTPStatus.BAD_REQUEST, data=response, safe=False)
...         else:
...             response = {'reason': 'Ok', 'detail': 'Product created'}
...             return JsonResponse(status=HTTPStatus.CREATED, data=response, safe=False)

File myproject/urls.py:

>>> path('api/v1/product/', ProductDetailAPI.as_view(), name='product-detail-api'),

17.1.4. Use Case - 0x01

>>> 
... import json
... from django.core.exceptions import ValidationError
... from django.http import HttpRequest, HttpResponse, JsonResponse
... from django.views.decorators.csrf import csrf_exempt
... from django.views.generic import View
... from shop.models import Product
...
...
... class ProductAPIView(View):
...     http_method_names = ['get', 'post']
...
...     @csrf_exempt
...     def dispatch(self, request, *args, **kwargs):
...         return super().dispatch(request, *args, **kwargs)
...
...     def get(self, request: HttpRequest, pk: int) -> HttpResponse:
...         try:
...             product = Product.objects.get(pk=pk)
...         except Product.DoesNotExist:
...             return JsonResponse(status=404, data={'status': 404, 'reason': 'Product not found'},)
...         else:
...             data = vars(product)
...             data.pop('_state')
...             return JsonResponse(status=200, data=data)
...
...     def post(self, request: HttpRequest) -> HttpResponse:
...         try:
...             data = json.loads(request.body.decode('utf-8'))
...         except json.JSONDecodeError:
...             return JsonResponse(status=400, data={'status': 400, 'reason': 'Bad Request'})
...         except Exception:
...             return JsonResponse(status=400, data={'status': 400, 'reason': 'Bad request'})
...
...         try:
...             Product.objects.create(ean13=data['ean13'], name=data['name'], price=data['price'])
...         except ValidationError:
...             return JsonResponse(status=422, data={'status': 422, 'reason': 'Unprocessable Content'})
...         else:
...             return JsonResponse(status=201, data={'status': 201, 'reason': 'Product created'})