Neste projeto, você vai praticar os seus conhecimentos em Django e Django Rest Framework. Você irá desenvolver uma API para gerenciamento de dados de perfil e projetos em um super portfólio. Vamos lá? 🤩
Neste projeto, verificamos se você é capaz de:
-
Utilizar o Django REST Framework para criar endpoints com entidades aninhadas.
-
Utilizar o módulo Simple JWT para implementar autenticação no Django REST Framework.
🏃🏾 Executando o Projeto
Para a realização deste projeto, utilizaremos um banco de dados chamado `super_portfolio_database`. Já existe um script de criação do banco pronto no arquivo `database/01_create_database.sql` que será copiado para dentro do container. Não altere este script.Para rodar o MySQL via Docker execute os seguintes comandos na raiz do projeto:
docker build -t super-portfolio-db . docker run -d -p 3306:3306 --name=super-portfolio-mysql-container -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=super_portfolio_database super-portfolio-db
Esses comandos irão fazer o build da imagem e subir o container Docker.
Lembre-se de que o MySQL utiliza por padrão a porta 3306. Se já houver outro serviço utilizando esta porta, considere desativá-lo ou mudar a porta no comando acima.
Você é uma pessoa desenvolvedora fullstack que já desenvolveu vários projetos enquanto estudava um conjunto de tecnologias específicas. Agora, sua atenção será direcionada para entrar para o mercado de trabalho e para isso, apresentar um portfólio com todos os seus projetos é algo importantíssimo. Seu objetivo aqui será desenvolver este portfólio com seu perfil, projetos, links importantes do seu LinkedIn e disponibilizá-lo para visualização por meio do deploy via Railway.
A seguir está o escopo de cada tarefa que te levará a conclusão do seu Super Portfólio! 🤩
🍀 Dica: Antes de iniciar a implementação da autenticação, certifique-se de que tanto o container Docker com o banco de dados quanto o servidor estão rodando.
✍️ Detalhes do requisito
- Implemente a autenticação com Simple JWT no projeto para que somente pessoas logadas possam ter acesso a aplicação.
- Use a rota
token/
para a obtenção do Token JWT. - Use a rota
token/refresh/
para a atualização do Token JWT. - Use a rota
token/verify/
para a verificação do Token JWT.
🤖 O que será verificado pelo avaliador
- Se ao usar credenciadas incorretas a autenticação falha.
- Se ao usar credenciadas corretas autenticação é bem sucedida.
- Se a rota de verificação de token está funcionando corretamente.
- Se a rota de atualização de token está funcionando corretamente.
Inicie um app com o nome projects
e crie um C.R.U.D. para o model Profile
. Para isso, você deve criar as rotas, views e serializers necessários para que seja possível realizar as operações de C.R.U.D. para a model Profile
.
🍀 Dica: Os requisitos seguintes exigirão a criação de modelos. Lembre-se que sempre que criar/modificar um modelo, é necessário criar as migrações para espelhar as modificações para os bancos de dados, inclusive o banco de testes contam com estas modificações. O comando para gerar a migration a partir dos modelos criados é:
python3 manage.py makemigrations
✍️ Detalhes do requisito
✍️ Model Profile
-
Crie a classe
Profile
. -
A classe
Profile
deve herdar osmodels
do Django. -
A classe
Profile
deve ter as propriedades:name
,github
,linkedin
, ebio
. -
A propriedade
name
deve ser um campo de caracteres com um tamanho máximo de 100 caracteres. -
As propriedades
github
,linkedin
devem ser campos de URL. -
A propriedade
bio
deve ser um campo de texto sem tamanho máximo definido. -
As propriedades devem ser:
name
: Campo de caracteres, com tamanho máximo de 50 caracteres.github
: Campo de URL.linkedin
: Campo de URL.bio
: Campo de texto, sem tamanho máximo definido.
-
As propriedades
name
,github
,linkedin
, ebio
não devem aceitar informações vazias ou maiores que 500 caracteres. -
O método
__str__
da classeProfile
deve retornar a propriedadename
do perfil criado.
✍️ Rotas
As operações do C.R.U.D. devem ser acessadas apor meio da rota: profiles/
, a partir da URL base http://localhost:8000/
. Em que:
- A rota
profiles
deve aceitar requisições do tipoGET
e retornar uma lista com todos os perfis cadastrados. - A rota
profiles/
deve aceitar requisições do tipoPOST
e criar um novo perfil com as informações passadas. - A rota
profiles/<id_do_perfil>
deve aceitar requisições do tipoGET
e retornar o perfil com oid
especificado. - A rota
profiles/<id_do_perfil>/
deve aceitar requisições do tipoPATCH
e atualizar o perfil com oid
especificado. - A rota
profiles/<id_do_perfil>/
deve aceitar requisições do tipoDELETE
e deletar o perfil com oid
especificado.
🤖 O que será verificado pelo avaliador
- Se o app iniciado se chama
projects
. - Se o app criado está devidamente instalado no
settings.py
. - Se o endpoint
http://localhost:8000/profiles
existe. - Se ao acessar a rota
profiles
devidamente autenticado será retornada uma lista completa com todos os perfis cadastrados. - Se a rota
profiles
aceitar requisições do tipoPOST
e cria um novo perfil se a pessoa usuária estiver devidamente autenticada. - Se a rota
profiles/<id_do_perfil>
aceita requisições do tipoGET
e retorna o perfil com oid
especificado, se a pessoa usuária estiver devidamente autenticada. - Se a rota
profiles/<id_do_perfil>/
aceita requisições do tipoPATCH
e atualiza o perfil com oid
especificado, se a pessoa usuária estiver devidamente autenticada. - Se a rota
profiles/<id_do_perfil>/
aceita requisições do tipoDELETE
e deleta o perfil com oid
especificado, se a pessoa usuária estiver devidamente autenticada.
Crie um C.R.U.D. para o model Project
. Para isso, você deve criar as rotas, views e serializers necessários para que seja possível realizar as operações de C.R.U.D. para a model Project
.
✍️ Detalhes do requisito
✍️ Model Project
- Crie a classe
Project
. - A classe
Project
deve herdar osmodels
do Django. - A classe
Project
deve ter as propriedades:name
,description
,github_url
,keyword
,key_skill
eprofile
. - As propriedades
name
,keywords
ekey_skill
devem ser campos de caracteres com um tamanho máximo de 50 caracteres. - A propriedade
description
deve ser um campo de texto com um tamanho máximo de 500 caracteres. - A propriedade
github_url
deve ser um campo de URL. - A propriedade
profile
deve ser um campo de relacionamento com a classeProfile
. - As propriedades devem ser:
name
: Campo de caracteres, com tamanho máximo de 50 caracteres.description
: Campo de texto, , com tamanho máximo de 500 caracteres.github_url
: Campo de URL.keyword
: Campo de caracteres, com tamanho máximo de 50 caracteres.key_skill
: Campo de caracteres, com tamanho máximo de 50 caracteres.profile
: Campo de chave estrangeira(foreign key) com a classeProfile
.
- As propriedades
name
,description
,github_url
,keywords
ekey_skills
não devem aceitar informações vazias ou maiores que 500 caracteres. - O relacionamento presente em
profile
deve ser do tipo1:N
, em que um perfil pode ter vários projetos. - O método
__str__
da classeProject
deve retornar a propriedadename
do projeto criado.
🍀 Dicas: Existe um tipo de campo específico pra URLs no Django. Para saber mais, acesse a documentação. 😉
✍️ Rotas
As operações do C.R.U.D. devem ser acessadas apor meio da rota: projects/
, a partir da URL base http://localhost:8000/
. Em que:
- As rotas
projects/
eprojects/<id_do_projeto>/
devem ser acessíveis apenas por pessoas usuárias autenticadas. - A rota
projects/
deve aceitar requisições do tipoGET
e retornar uma lista com todos os projetos cadastrados. - A rota
projects/
deve aceitar requisições do tipoPOST
e criar um novo projeto com as informações passadas. - A rota
projects/<id_do_projeto>/
deve aceitar requisições do tipoGET
e retornar o projeto com oid
especificado. - A rota
projects/<id_do_projeto>/
deve aceitar requisições do tipoPATCH
e atualizar o projeto com oid
especificado. - A rota
projects/<id_do_projeto>/
deve aceitar requisições do tipoDELETE
e deletar o projeto com oid
especificado.
🤖 O que será verificado pelo avaliador
- Se o endpoint
http://localhost:8000/projects
existe. - Se ao acessar a rota
projects
devidamente autenticado será retornada uma lista completa com todos os projetos cadastrados. - Se a rota
projects
aceita requisições do tipoPOST
e cria um novo projeto se a pessoa usuária estiver devidamente autenticada. - Se a rota
projects/<id_do_projeto>/
aceita requisições do tipoGET
e retorna o projeto com oid
especificado, se a pessoa usuária estiver devidamente autenticada. - Se a rota
projects/<id_do_projeto>/
aceita requisições do tipoPATCH
e atualiza o projeto com oid
especificado, se a pessoa usuária estiver devidamente autenticada. - Se a rota
projects/<id_do_projeto>/
aceita requisições do tipoDELETE
e deleta o projeto com oid
especificado, se a pessoa usuária estiver devidamente autenticada.
Customize a ViewSet de Profile
para que as rotas do tipo GET
possam ser acessadas sem a necessidade de autenticação, renderizando diretamente um template com todas as informações pertinentes ao invés de haver retorno da API.
🍀 Dica: Há como definir uma função dentro de uma ViewSet que dá diferentes permissões de acesso para diferentes métodos HTTP conforme o tipo de requisição. No caso deste requisito, por exemplo, o método GET é permitido para qualquer pessoa, enquanto os outros métodos (POST, PATCH e DELETE) requerem autenticação. Desta forma, a função que faz a diferenciação de permissões de acesso deve ser definida dentro da ViewSet pode ser definida da seguinte forma:
def get_permissions(self):
if self.request.method == 'GET':
return [AllowAny()]
return [IsAuthenticated()]
✍️ Detalhes do requisito
- Crie uma classe chamada
ProfileViewSet
emprojects/views.py
. - Essa classe deve herdar de
ModelViewSet
. - A classe
ProfileViewSet
deve ter uma função que exige autenticação a depender do método utilizado na requisição. - As rotas do tipo
GET
podem ser acessadas sem a necessidade de autenticação, renderizando diretamente um template com todas as informações pertinentes. - As rotas do tipo
POST
,PATCH
eDELETE
só podem ser acessadas por pessoas usuárias autenticadas. - Utilize o método
retrieve
para exibir os detalhes de um perfil (profile), renderizando um template HTML com esses detalhes e informações relacionadas. Esse método deve verificar se a requisição é umGET
e, se não for, chamar a implementação padrão de recuperação de detalhes usandosuper().retrieve()
. - Após recuperar o perfil, renderize um template HTML com o perfil. O template deve ser criado no caminho
projects/templates/profile_detail.html
.
🍀 Dica: A função
retrieve
é chamada quando o Viewset recebe, entre outras possibilidades, a requisiçãoGET
. Customizando ela, conseguimos direcionar cada verbo HTTP para uma renderiza'ncção de dados diferente . Desta forma, você pode utilizar a função abaixo como base para desenvolver o que é solicitado:
class ProfileViewSet(viewsets.ModelViewSet):
# defina a queryset
# defina a classe do serializer
def get_permissions(self):
if self.request.method == 'GET':
return [AllowAny()]
return [IsAuthenticated()]
def retrieve(self, request, *args, **kwargs):
if request.method == 'GET':
# busque o id do perfil
# crie uma variável para guardar esse perfil
return render(
# passe os parâmetros necessários para o template:
# a requisição, o caminho do template e um dict com dados para o template
)
return super().retrieve(request, *args, **kwargs)
🤖 O que será verificado pelo avaliador
- Se o endpoint
http://localhost:8000/profiles
existe. - Se ao acessar a rota
profiles
mesmo sem autenticação será retornada uma lista completa com todos os perfis cadastrados. - Se a rota
profiles/<id_do_perfil>/
aceita requisições do tipoGET
e retorna o perfil com oid
especificado. - Se a rota
profiles
aceita requisições do tipoPOST
e cria um novo perfil se a pessoa usuária estiver devidamente autenticada. - Se a rota
profiles/<id_do_perfil>/
aceita requisições do tipoPATCH
e atualiza o perfil com oid
especificado, se a pessoa usuária estiver devidamente autenticada. - Se a rota
profiles/<id_do_perfil>/
aceita requisições do tipoDELETE
e deleta o perfil com oid
especificado, se a pessoa usuária estiver devidamente autenticada.
Crie um C.R.U.D. inline para o model Certificate
e CertifyingInstitution
, para que em uma única requisição seja possível ver/criar as instituições certificadoras e seus respectivos certificados em uma única requisição. Para isso, você deve criar as rotas, views e serializers necessários para que seja possível realizar as operações de C.R.U.D. para as models Certificate
e CertifyingInstitution
.
🍀 Dica: Para criar um C.R.U.D. inline, você deve herdar do
serializers.ModelSerializer
no serializer que conterá a outra entidade, para definir um atributo que contenha uma instância do serializer a ser contido. Neste momento você pode usar o argumento(many=True)
para indicar que o campo de relacionamento representa vários objetos relacionados, ou seja, serializando várias certificações para uma instituição certificadora. Além disso, você deve sobrescrever a funçãocreate
do serializer.
✍️ Detalhes do requisito
✍️ Model CertifyingInstitution
- Crie a classe
CertifyingInstitution
. - A classe
CertifyingInstitution
deve herdar osmodels
do Django. - A classe
CertifyingInstitution
deve ter as propriedades:name
eurl
. - A propriedade
name
deve ser um campo de caracteres com um tamanho máximo de 100 caracteres. - A propriedade
url
deve ser um campo de URL. - As propriedades
name
eurl
não devem aceitar informações vazias ou maiores que 500 caracteres. - O método
__str__
da classeCertifyingInstitution
deve retornar a propriedadename
da instituição certificadora criada.
✍️ Model Certificate
- Crie a classe
Certificate
. - A classe
Certificate
deve herdar osmodels
do Django. - A classe
Certificate
deve ter as propriedades:name
,certifying_institution
,timestamp
eprofiles
. - A propriedade
name
deve ser um campo de caracteres com um tamanho máximo de 100 caracteres. - A propriedade
certifying_institution
deve ser um campo de relacionamento de chave estrangeira com a classeCertifyingInstitution
. - A propriedade
timestamp
deve ser um campo de data e hora preenchido automaticamente no momento de sua criação. - A propriedade
profiles
deve ser um campo de relacionamento do tipoManyToMany
com a classeProfile
com o atributorelated_name
definido comocertificates
. - As propriedades
name
,certifying_institution
,timestamp
, eprofiles
não devem aceitar informações vazias ou maiores que 500 caracteres. - O método
__str__
da classeCertificate
deve retornar a propriedadename
do certificado criado.
✍️ Rotas
As operações do C.R.U.D. devem ser acessadas apor meio das rotas: certificates/
, e certifying-institutions/
a partir da URL base http://localhost:8000/
. Em que:
-
As rotas
certificates/
ecertificates/<id_do_certificado>/
devem ser acessíveis apenas por pessoas usuárias autenticadas. -
A rota
certificates/
deve aceitar requisições do tipoGET
e retornar uma lista com todos os certificados cadastrados. -
A rota
certificates/
deve aceitar requisições do tipoPOST
e criar um novo certificado com as informações passadas. -
A rota
certificates/<id_do_certificado>/
deve aceitar requisições do tipoGET
e retornar o certificado com oid
especificado. -
A rota
certificates/<id_do_certificado>/
deve aceitar requisições do tipoPATCH
e atualizar o certificado com oid
especificado. -
A rota
certificates/<id_do_certificado>/
deve aceitar requisições do tipoDELETE
e deletar o certificado com oid
especificado. -
As rotas
certifying-institutions/
ecertifying-institutions/<id_da_instituição-certificadora>/
devem ser acessíveis apenas por pessoas usuárias autenticadas. -
A rota
certifying-institutions/
deve aceitar requisições do tipoGET
e retornar uma lista com todas as instituições certificadoras cadastradas. -
A rota
certifying-institutions/
deve aceitar requisições do tipoPOST
e criar uma nova instituição certificadora com as informações passadas. Essa instituição deve conter pelo menos um certificado para ser criada. -
A rota
certifying-institutions/<id_da_instituição-certificadora>/
deve aceitar requisições do tipoGET
e retornar a instituição certificadora com oid
especificado. -
A rota
certifying-institutions/<id_da_instituição-certificadora>/
deve aceitar requisições do tipoPATCH
e atualizar a instituição certificadora com oid
especificado. Não é necessário que as atualizações possam ser inline também. -
A rota
certifying-institutions/<id_da_instituição-certificadora>/
deve aceitar requisições do tipoDELETE
e deletar a instituição certificadora com oid
especificado.
🤖 O que será verificado pelo avaliador
-
Se o endpoint
http://localhost:8000/certificates/
existe. -
Se ao acessar a rota
certificates
devidamente autenticado será retornada uma lista completa com todos os certificados cadastrados. -
Se a rota
certificates
aceita requisições do tipoPOST
e cria um novo certificado se a pessoa usuária estiver devidamente autenticada. -
Se a rota
certificates/<id_do_certificado>/
aceita requisições do tipoGET
e retorna o certificado com oid
especificado, se a pessoa usuária estiver devidamente autenticada. -
Se a rota
certificates/<id_do_certificado>/
aceita requisições do tipoPATCH
e atualiza o certificado com oid
especificado, se a pessoa usuária estiver devidamente autenticada. -
Se a rota
certificates/<id_do_certificado>/
aceita requisições do tipoDELETE
e deleta o certificado com oid
especificado, se a pessoa usuária estiver devidamente autenticada. -
Se o endpoint
http://localhost:8000/certifying-institutions/
existe. -
Se ao acessar a rota
certifying-institutions
devidamente autenticado será retornada uma lista completa com todos os certificados cadastrados. -
Se a rota
certifying-institutions
aceita requisições do tipoPOST
e cria uma nova instituição certificadora se a pessoa usuária estiver devidamente autenticada. -
Se a rota
certifying-institutions/<id_da_instituição-certificadora>/
aceita requisições do tipoGET
e retorna a instituição certificadora com oid
especificado, se a pessoa usuária estiver devidamente autenticada. -
Se a rota
certifying-institutions/<id_da_instituição-certificadora>/
aceita requisições do tipoPATCH
e atualiza a instituição certificadora com oid
especificado, se a pessoa usuária estiver devidamente autenticada. -
Se a rota
certifying-institutions/<id_da_instituição-certificadora>/
aceita requisições do tipoDELETE
e deleta a instituição certificadora com oid
especificado, se a pessoa usuária estiver devidamente autenticada.
O template de Profile
deve ser atualizado para que seja possível visualizar todas as informações de um perfil, incluindo seus certificados e instituições certificadoras.
🍀 Dica: Para que seja possível exibir também os certificados, você precisará alterar a função
retrieve
, nas views.
✍️ Detalhes do requisito
- Ao acessar um perfil, deve ser possível visualizar os certificados e instituições certificadoras de um perfil.
🤖 O que será verificado pelo avaliador
- Se ao acessar um perfil é ser possível visualizar os certificados e instituições certificadoras dele.
- O projeto deve ter seu nome, habilidade-chave e palavra-chave exibidas.
- O certificado deve exibir seu nome e o nome de sua instituição certificadora.
Para que seu projeto esteja acessível e pronto para ser visualizado por pessoas de recrutamento, fazer deploy dele pode ser um grande diferencial. Lembre-se que sempre que precisar, você pode consultar o material sobre deploy com Django do curso. 😉