Pular para o conteúdo
Ramos da Informática - Comunidade de Desenvolvedores

Torne-se um desenvolvedor FullStack: Pacote completo de formação desenvolvedor Frontend e Backend utilizando as linguagens de programação e frameworks mais procurados no mercado de trabalho. Mais informações, aqui. Faça o download do E-BookGuia Completo Para Se Tornar um(a) Desenvolvedor(a) Full-Stack, Começando do ZERO”.

Engenheiro de Software, autor de livros sobe tecnologia e negócios. É mantenedor do site Ramos da Informática. Hobbies: investir em ações, natação e finanças.

Engenheiro de Software, autor de livros sobe tecnologia e negócios. É mantenedor do site Ramos da Informática. Hobbies: investir em ações, natação e finanças.

admin

Todos os artigos deste autor

Django Rest Framework Serialization

Chatbots com Whatsapp e Cielo integrados Nesse curso, eu vou te mostrar como o consumidor poder realizar um pagamento por dentro do aplicativo do WhatsApp, aonde o seu cliente vai entrar numa conversa como entraria numa conversa com qualquer pessoa ou com a sua empresa, navegar entre os produtos/serviços em menus simples enviados pelo chatbot, adicionar esses produtos/serviços no carrinho de compras, e num determinado ponto do chat, um link exclusivo é enviado para o cliente preencher os dados do cartão de crédito. No final, a análise é devolvida para o Whatsapp no qual a conversa foi iniciada. Inscreva-se.

Eu resolvi estudar um pouco mais de DRF depois do tutorial do Hugo Brilhante na Python Brasil 11.

Este artigo foi atualizado em 14 de Fevereiro de 2018.

Este artigo está usando:

Python 3.5.2
Django 2.0.2
djangorestframework 3.7.7

Favor clonar o projeto do GitHub, favor ler o README para instalação.

Obs: se você não sabe Django sugiro que leia este tutorial antes.

Obs: Tem coisas que é melhor nem traduzir. 😉

Pra quem não sabe, para usar API Web usamos REST, no caso, Django Rest Framework, framework web do Django.

Nota: este tutorial não é exatamente igual ao do Hugo, é baseado nele. E baseado também em Tutorial 1: Serialization.

Então para criar a API, no meu caso, eu usei:

Ambiente: .venv
Projeto: myproject
App: core
Model: Person
Fields: first_name, last_name, email, active (boolean), created

Configurando um novo ambiente

$ python3 -m venv .venv
$ source .venv/bin/activate
$ mkdir drf; cd drf
$ pip install django==2.0.2 djangorestframework==3.7.7
$ pip install django-filter drf-nested-routers
$ pip freeze > requirements.txt
$ django-admin.py startproject myproject .
$ python manage.py startapp core

Veja o meu requirements.txt

dj-database-url==0.4.2
Django==2.0.2
django-extensions==1.9.9
django-filter==1.1.0
djangorestframework==3.7.7
drf-nested-routers==0.90.0
python-decouple==3.1

Step-0 Projeto inicial

Abra o arquivo settings.py e em INSTALLED_APPS acrescente

INSTALLED_APPS = (

‘rest_framework’,
‘core’,
)

Step-1 Serializer

models.py: Criando o modelo Person

from django.db import models

class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField(null=True, blank=True)
active = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True, auto_now=False)

class Meta:
ordering = [‘first_name’]
verbose_name = u‘pessoa’
verbose_name_plural = u‘pessoas’

def __str__(self):
return self.first_name + ” “ + self.last_name

full_name = property(__str__)

serializers.py: Criando PersonSerializer

Precisamos proporcionar uma forma de serialização e desserialização das instâncias de person em uma representação JSON.

$ cd core/
$ touch serializers.py

Edite

from rest_framework import serializers
from core.models import Personclass PersonSerializer(serializers.Serializer):
pk = serializers.IntegerField(read_only=True)
first_name = serializers.CharField(max_length=30)
last_name = serializers.CharField(max_length=30)
email = serializers.EmailField()
active = serializers.BooleanField(default=True)
created = serializers.DateTimeField()

def create(self, validated_data):
“””
Create and return a new `Person` instance, given the validated data.
:param validated_data:
“””
return Person.objects.create(**validated_data)

def update(self, instance, validated_data):
“””
Update and return an existing `Person` instance, given the validated data.
“””

instance.first_name = validated_data.get(
‘first_name’, instance.first_name)
instance.last_name = validated_data.get(
‘last_name’, instance.last_name)
instance.email = validated_data.get(’email’, instance.email)
instance.save()
return instance

A primeira parte da classe define os campos que serão serializados. Os métodos create() e update() criam e atualizam as instâncias, respectivamente, quando chamados.

Uma classe de serialização é similar a uma classe Form do Django, e inclui validações similares para os campos, tais como required, max_length e default.

Fazendo a migração

$ ./manage.py makemigrations core
$ ./manage.py migrate

Trabalhando com a serialização

Abra o shell do Django.

$ ./manage.py shell

Primeiro vamos criar uma pessoa.

>>> from core.models import Person
>>> from core.serializers import PersonSerializer
>>> from rest_framework.renderers import JSONRenderer
>>> from rest_framework.parsers import JSONParser>>> person = Person(first_name=‘Paul’, last_name=‘Van Dyke’, email=‘paul@email.com’)
>>> person.save()

>>> person = Person(first_name=‘Regis’, last_name=‘Santos’, email=‘regis@email.com’)
>>> person.save()

Agora que já temos alguns dados podemos ver a serialização da última instância.

>>> serializer = PersonSerializer(person)
>>> serializer.data
# {‘pk’: 2, ‘first_name’: ‘Regis’, ‘created’: ‘2015-11-15T03:20:25.084990Z’, ‘last_name’: ‘Santos’, ’email’: ‘regis@email.com’, ‘active’: True}

Neste ponto nós traduzimos a instância do modelo em tipos de dados nativos do Python. Para finalizar o processo de serialização nós vamos renderizar os dados em json.

>>> content = JSONRenderer().render(serializer.data)
>>> content
# b'{“pk”:2,”first_name”:”Regis”,”last_name”:”Santos”,”email”:”regis@email.com”,”active”:true,”created”:”2015-11-15T03:20:25.084990Z”}’

A desserialização é similar.

>>> from core.models import Person
>>> from core.serializers import PersonSerializer
>>> from rest_framework.renderers import JSONRenderer
>>> from rest_framework.parsers import JSONParser
>>> from django.utils.six import BytesIO>>> person = Person.objects.get(pk=1)
>>> serializer = PersonSerializer(person)
>>> content = JSONRenderer().render(serializer.data)
>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> serializer = PersonSerializer(data=data)
>>> serializer.is_valid()
# True
>>> serializer.validated_data
# OrderedDict([(‘first_name’, ‘Paul’), (‘last_name’, ‘Van Dyke’), (’email’, ‘paul@email.com’), (‘active’, True)])

Step-2 ModelSerializer

Nossa classe PersonSerializer está replicando um monte de informações que está contido no modelo Person.

Da mesma forma que o Django fornece Form e ModelForm, REST framework inclui as classes Serializer e ModelSerializer.

Vamos refatorar nosso arquivo serializers.py, que agora ficará assim:

from rest_framework import serializers
from core.models import Personclass PersonSerializer(serializers.ModelSerializer):

class Meta:
model = Person
fields = (‘pk’, ‘first_name’, ‘last_name’,’email’, ‘active’, ‘created’)

Uma propriedade legal que a serialização tem é que você pode inspecionar todos os campos em uma instância serializer, imprimindo sua representação. Abra o shell do Django.

$ ./manage.py shell
>>> from core.serializers import PersonSerializer
>>> serializer = PersonSerializer()
>>> print(repr(serializer))
# PersonSerializer():
# pk = IntegerField(label=’ID’, read_only=True)
# first_name = CharField(max_length=30)
# last_name = CharField(max_length=30)
# email = EmailField(allow_blank=True, allow_null=True, max_length=254, required=False)
# active = BooleanField(required=False)
# created = DateTimeField(read_only=True)

É importante lembrar que as classes ModelSerializer não faz nenhuma mágica, são simplesmente um atalho para a criação das classes de serialização:

Os campos são definidos automaticamente.
Os métodos create() e update() são implementados por padrão de uma forma simplificada.

views.py: Criando views regulares usando nosso Serializer

Vamos criar uma view simples para visualizar os dados em json.

Edite o arquivo views.py

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from core.models import Person
from core.serializers import PersonSerializerclass JSONResponse(HttpResponse):
“””
An HttpResponse that renders its content into JSON.
“””

def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs[‘content_type’] = ‘application/json’
super(JSONResponse, self).__init__(content, **kwargs)

A raiz da nossa API será uma lista de todas as pessoas, ou podemos criar uma pessoa nova.

@csrf_exempt
def person_list(request):
“””
List all persons, or create a new person.
“””
if request.method == ‘GET’:
persons = Person.objects.all()
serializer = PersonSerializer(persons, many=True)
return JSONResponse(serializer.data)elif request.method == ‘POST’:
data = JSONParser().parse(request)
serializer = PersonSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data, status=201)
return JSONResponse(serializer.errors, status=400)

Note que nós queremos usar o POST mas não temos o CSRF Token, por isso usamos o @csrf_exempt.

Também vamos precisar visualizar os detalhes de cada pessoa. Assim podemos recuperar, atualizar ou deletar cada registro.

@csrf_exempt
def person_detail(request, pk):
“””
Retrieve, update or delete a person.
“””
try:
person = Person.objects.get(pk=pk)
except Person.DoesNotExist:
return HttpResponse(status=404)if request.method == ‘GET’:
serializer = PersonSerializer(person)
return JSONResponse(serializer.data)

elif request.method == ‘PUT’:
data = JSONParser().parse(request)
serializer = PersonSerializer(person, data=data)
if serializer.is_valid():
serializer.save()
return JSONResponse(serializer.data)
return JSONResponse(serializer.errors, status=400)

elif request.method == ‘DELETE’:
person.delete()
return HttpResponse(status=204)

Agora, vamos criar as urls. Crie um novo arquivo core/urls.py.

from django.urls import path
from core import viewsurlpatterns = [
path(‘persons/’, views.PersonList.as_view()),
path(‘persons/<int:pk>/’, views.PersonDetail.as_view()),
]

E acrescente a seguinte linha em myproject/urls.py.

from django.urls import include, path
from django.contrib import adminurlpatterns = [
path(, include(‘core.urls’)),
path(‘admin/’, admin.site.urls),
]

Instalando httpie

Podemos usar o curl, mas o httpie é mais amigável, e escrito em Python.

$ sudo pip install httpie

Vamos usar o httpie digitando

$ http http://127.0.0.1:8000/persons/

HTTP/1.0 200 OK
Content-Type: application/json
Date: Sun, 15 Nov 2015 03:24:44 GMT
Server: WSGIServer/0.2 CPython/3.4.3
X-Frame-Options: SAMEORIGIN

[
{
“active”: true,
“created”: “2015-11-15T03:20:24.938378Z”,
“email”: “paul@email.com”,
“first_name”: “Paul”,
“last_name”: “Van Dyke”,
“pk”: 1
},
{
“active”: true,
“created”: “2015-11-15T03:20:25.084990Z”,
“email”: “regis@email.com”,
“first_name”: “Regis”,
“last_name”: “Santos”,
“pk”: 2
}
]

Veja os detalhes

$ http http://127.0.0.1:8000/persons/1/

Atenção: se você receber erro 301, muito provavelmente é porque você esqueceu da barra / no final da url.

Como seria em curl?

Assim

$ curl http://127.0.0.1:8000/persons/

[{“pk”:1,“first_name”:“Paul”,“last_name”:“Van Dyke”,“email”:“paul@email.com”,“active”:true,“created”:“2015-11-15T03:20:24.938378Z”},{“pk”:2,“first_name”:“Regis”,“last_name”:“Santos”,“email”:“regis@email.com”,“active”:true,“created”:“2015-11-15T03:20:25.084990Z”}]

GitHub: Se você quiser pode olhar meu GitHub, mas terá que ver os commits para ver os passos.

Este artigo foi importado automaticamente por fazer parte do Planetário Dev. Quer fazer parte deste HUB de conteúdos? Faça parte do Planetário e veja as vantagens.

Não tem site ou blog? Seja um autor do site e ainda pode ser remunerado.

Leia também:

Facebook
LinkedIn
Twitter
Pinterest
Reddit
Telegram
WhatsApp
Email
Print

Relacionados

Deixe uma resposta