Django Rest framework – Relationship Models -Relaciones del modelo Categoría y Producto

En este tutorial vamos a aprender de hacer un CRUD con tablas relaciones de producto y categoría, crearemos un API Rest usando el framework Django Rest Framework.

1 – Crear entorno virtual

python -m venv venv
Activar
#windows 
venv\Scripts\activate.bat
.\venv\Scripts\activate.bat
#linux or mac
source venv/bin/activate

2 – Instalar Django

pip install django djangorestframework

3 – Iniciar proyecto

django-admin startproject company
cd company

4.1 – Instalar PostgreSQL

pip install psycopg2

Configurar conexión

company\settings.py

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'tutofox',
        'USER': 'postgres',
        'PASSWORD': '12345',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

...

4.2 – Instalar MySQL

pip install pymysql

companey\__init__.py

import pymysql
pymysql.version_info = (1, 4, 3, "final", 0)
pymysql.install_as_MySQLdb()

company\settings.py

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

...

5 – Migrate

python manage.py migrate

Categoría

6 – Crear app

django-admin startapp category

Configurar app

company\settings.py

...

INSTALLED_APPS = [
 	...
    'rest_framework',
    'category'
]

...

7 – Model

category\models.py

from django.db import models 
 
class CategoryModel(models.Model):
    name = models.CharField(max_length=255) 
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = "category"

8 – Serialize

category\serializers.py

from rest_framework import serializers
from category.models import CategoryModel


class CategorySerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    class Meta:
        model = CategoryModel
        fields = ['id', 'name']

9 – Views

category\views.py

from rest_framework import status
from rest_framework.views import APIView 
from rest_framework.response import Response
from category.models import CategoryModel
from category.serializers import CategorySerializer 

class CategoryApiView(APIView):
    def get(self, request):
        serializer = CategorySerializer(CategoryModel.objects.all(), many=True)
        return Response(status=status.HTTP_200_OK, data=serializer.data)
    def post(self, request): 
        #res = request.data.get('name')  
        serializer = CategorySerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(status=status.HTTP_200_OK, data=serializer.data)

class CategoryApiViewDetail(APIView):
    def get_object(self, pk):
        try:
            return CategoryModel.objects.get(pk=pk)
        except CategoryModel.DoesNotExist:
            return None
    def get(self, request, id):
        post = self.get_object(id)
        serializer = CategorySerializer(post)  
        return Response(status=status.HTTP_200_OK, data=serializer.data)
    def put(self, request, id):
        post = self.get_object(id)
        if(post==None):
            return Response(status=status.HTTP_200_OK, data={ 'error': 'Not found data'})
        serializer = CategorySerializer(post, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(status=status.HTTP_200_OK, data=serializer.data) 
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, id):
        post = self.get_object(id)
        post.delete()
        response = { 'deleted': True }
        return Response(status=status.HTTP_204_NO_CONTENT, data=response)

9 – Urls

category\urls.py

from django.urls import path
from category.views import CategoryApiView, CategoryApiViewDetail
  
urlpatterns_category = [
    path('v1/category', CategoryApiView.as_view()), 
    path('v1/category/<int:id>', CategoryApiViewDetail.as_view()), 
]

company\urls.py

from django.contrib import admin
from django.urls import path, include
from category.urls import urlpatterns_category

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(urlpatterns_category)),
] 

10 – Start API Server

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Producto

11 – Crear app

django-admin startapp product

Configurar app

company\settings.py

...

INSTALLED_APPS = [
 	...
    'rest_framework',
    'category',
    'product'
]

...

12 – Model

product\models.py

from django.db import models
from django.db.models import SET_NULL 
from category.models import CategoryModel


class ProductModel(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    price = models.BigIntegerField()
    published = models.BooleanField(default=False) 
    created_at = models.DateTimeField(auto_now_add=True)
    category = models.ForeignKey(CategoryModel, on_delete=SET_NULL, null=True)

    def __str__(self):
        return self.name

13 – Serialize

product\serializers.py

from rest_framework import serializers
from product.models import ProductModel
from category.serializers import CategorySerializer
from category.models import CategoryModel


class ProductSerializer(serializers.ModelSerializer): 
    category = CategorySerializer() 

    class Meta:
        model = ProductModel
        fields = ['name', 'description', 'price', 'published', 'category']

    def create(self, validated_data):
        category_post = validated_data.pop("category")
        category_data = CategoryModel.objects.get(pk=category_post['id'])
        product = ProductModel.objects.create(category=category_data,**validated_data)
       
        return product
        
     def update(self, instance, validated_data):
         
        instance.name = validated_data.pop('name', instance.name)
        instance.description = validated_data.pop('description', instance.description)
        instance.price = validated_data.pop('price', instance.price)
        instance.published = validated_data.pop('published', instance.published)
         
        category_post = validated_data.pop("category")
        category_data = CategoryModel.objects.get(pk=category_post['id'])
        instance.category = category_data
        instance.save()
        return instance 
        
        

14 – Views

product\views.py

from rest_framework import status
from rest_framework.views import APIView 
from rest_framework.response import Response

from product.models import ProductModel
from product.serializers import ProductSerializer 
from category.serializers import CategorySerializer
 
class ProductApiView(APIView):
    def get(self, request):
        queryset = ProductModel.objects.all()
        serializer = ProductSerializer( queryset, many=True)
        return Response(status=status.HTTP_200_OK, data=serializer.data)
    def post(self, request): 
        #res = request.data.get('name')  
        print(request.data.get('category'))
        #catg_serializer = CategorySerializer(data=request.data.get('category'))
        serializer = ProductSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(status=status.HTTP_200_OK, data=serializer.data)

class ProductApiViewDetail(APIView):
    def get_object(self, pk):
        try:
            return ProductModel.objects.get(pk=pk)
        except ProductModel.DoesNotExist:
            return None
    def get(self, request, id):
        product = self.get_object(id)
        serializer = ProductSerializer(product)  
        return Response(status=status.HTTP_200_OK, data=serializer.data)
    def put(self, request, id):
        product = self.get_object(id)
        if(product==None):
            return Response(status=status.HTTP_200_OK, data={ 'error': 'Not found data'})
        serializer = ProductSerializer(product, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(status=status.HTTP_200_OK, data=serializer.data) 
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, id):
        product = self.get_object(id)
        product.delete()
        response = { 'deleted': True }
        return Response(status=status.HTTP_204_NO_CONTENT, data=response)        

15 – Urls

product\urls.py

from django.urls import path
from product.views import ProductApiView, ProductApiViewDetail
  
urlpatterns_product = [
    path('v1/product', ProductApiView.as_view()), 
    path('v1/product/<int:id>', ProductApiViewDetail.as_view()), 
]

company\urls.py

from django.contrib import admin
from django.urls import path, include
from product.urls import urlpatterns_product
from category.urls import urlpatterns_category

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(urlpatterns_product)),
    path('api/', include(urlpatterns_category)),
] 

https://github.com/artyom-developer/django-rest-framework-relationship-models

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *