Category: Tutorial

  • Tipos de Dados no Python | Postagem 2

    Tipos de Dados no Python | Postagem 2

    Em Python, os tipos de dados são fundamentais para a construção de qualquer programa. Eles definem como os valores são armazenados e manipulados dentro do código. Cada dado inserido em uma variável possui um tipo específico, como inteiros (int), números de ponto flutuante (float), strings (str) e booleanos (bool). Compreender esses tipos é essencial para evitar erros e otimizar a execução de scripts e aplicações.

    Um dos principais motivos para entender os tipos de dados no Python é a tipagem dinâmica da linguagem. Isso significa que você não precisa declarar explicitamente o tipo de uma variável, pois o Python determina automaticamente com base no valor atribuído. No entanto, essa flexibilidade pode levar a erros inesperados caso haja manipulação inadequada dos dados. Por exemplo, tentar somar uma string com um inteiro resultará em um erro de TypeError.

    Outro ponto crucial é a eficiência do código. Escolher o tipo de dado correto pode melhorar a performance e reduzir o consumo de memória. Por exemplo, ao armazenar grandes quantidades de números, optar por inteiros ao invés de floats pode ser mais eficiente, pois os floats ocupam mais espaço na memória. Além disso, a manipulação de estruturas de dados como listas e dicionários se torna mais poderosa quando se conhece bem os diferentes tipos de dados.

    A seguir, veremos em detalhes os principais tipos de dados do Python, suas características e como utilizá-los de forma eficiente para evitar armadilhas comuns na programação.

    Números em Python

    Em Python, os números são um dos tipos de dados mais fundamentais e são amplamente utilizados em cálculos, estatísticas e manipulação de dados. Existem dois principais tipos numéricos: inteiros (int) e números de ponto flutuante (float). Cada um tem suas características e é essencial saber quando utilizá-los para evitar problemas de precisão e otimizar o desempenho do código.

    Os inteiros (int) representam números inteiros positivos e negativos, incluindo o zero. Eles são amplamente usados em contagens, índices de listas e operações matemáticas que não exigem casas decimais. No Python, não há limite de tamanho para inteiros, o que significa que você pode trabalhar com valores extremamente grandes sem precisar de uma configuração especial.

    x = 10  # Inteiro positivo
    y = -5  # Inteiro negativo
    z = 1000000000000  # Python permite inteiros muito grandes
    print(type(x))  # Saída: 
    Python

    Já os números de ponto flutuante (float) são utilizados para representar valores decimais, como 3.14 ou 0.001. Eles são essenciais para cálculos financeiros, operações trigonométricas e qualquer situação onde seja necessário um maior grau de precisão. Entretanto, por serem armazenados em um formato binário, os floats podem sofrer pequenas imprecisões em determinadas operações.

    a = 3.14  # Número decimal
    b = 2.0   # Mesmo sem casas decimais, é considerado float
    print(type(a))  # Saída: 
    Python

    A manipulação de números em Python é simples e direta, permitindo operações como soma (+), subtração (-), multiplicação (*) e divisão (/), além de funções matemáticas avançadas disponíveis no módulo math.

    import math
    
    soma = 10 + 5
    produto = 3 * 4
    raiz_quadrada = math.sqrt(16)  # Retorna 4.0
    
    print(soma, produto, raiz_quadrada)
    Python

    Compreender quando usar inteiros ou floats é essencial para garantir precisão e eficiência no código. Ao lidar com valores monetários, por exemplo, muitas vezes é preferível usar decimais da biblioteca decimal em vez de floats, para evitar erros de arredondamento.

    Strings no Python

    Em Python, as strings são um dos tipos de dados mais usados, representando sequências de caracteres que podem conter letras, números, espaços e símbolos. Elas são imutáveis, ou seja, uma vez criadas, seu conteúdo não pode ser alterado diretamente. Trabalhar com manipulação de strings é essencial para processar textos, gerar relatórios e lidar com entradas de usuários em aplicações web e scripts automatizados.

    Para criar uma string, basta atribuir um texto entre aspas simples (‘’), aspas duplas (“”) ou triplas (“”” “”” ou ”’ ”’).

    s1 = "Olá, mundo!"  # String com aspas duplas
    s2 = 'Python é incrível'  # String com aspas simples
    s3 = """Texto com múltiplas linhas"""  # Aspas triplas permitem múltiplas linhas
    print(s1, s2, s3)
    Python

    A concatenação de strings pode ser feita com o operador +, enquanto a repetição é realizada com *. Já a interpolação pode ser feita com f-strings, o método .format() ou %.

    nome = "Alice"
    mensagem = "Olá, " + nome + "!"  # Concatenação
    repeticao = "Python! " * 3  # Repetição
    interpolacao = f"Seja bem-vinda, {nome}!"  # Interpolação com f-strings
    print(mensagem, repeticao, interpolacao)
    Python

    O fatiamento (slicing) permite extrair partes de uma string usando índices. O primeiro caractere tem índice 0, e números negativos contam de trás para frente.

    texto = "Programação"
    print(texto[0:5])  # 'Progr'
    print(texto[-3:])  # 'ção'
    print(texto[::-1])  # Inverte a string ('oçamargorP')
    Python

    Além disso, o Python oferece diversos métodos úteis para transformar e manipular strings, como .upper(), .lower(), .replace() e .strip().

    frase = "  Python é poderoso!  "
    print(frase.upper())  # 'PYTHON É PODEROSO!'
    print(frase.lower())  # 'python é poderoso!'
    print(frase.replace("poderoso", "fantástico"))  # 'Python é fantástico!'
    print(frase.strip())  # Remove espaços extras
    Python

    Com essas técnicas, é possível trabalhar eficientemente com strings, garantindo maior flexibilidade ao processar textos e otimizar aplicações.

    Booleanos no Python

    Em Python, os booleanos são um tipo de dado fundamental que representa apenas dois valores possíveis: True (verdadeiro) e False (falso). Eles são amplamente usados em estruturas condicionais, laços de repetição e expressões lógicas, tornando-se essenciais para o controle de fluxo de qualquer programa. O Python trata True e False como subclasses de inteiros, onde True equivale a 1 e False equivale a 0.

    print(True + 1)  # Saída: 2
    print(False * 5)  # Saída: 0
    Python

    Os operadores lógicos (and, or, not) permitem a criação de condições mais avançadas. O and retorna True apenas se ambas as condições forem verdadeiras, enquanto o or retorna True se pelo menos uma for verdadeira. O not inverte o valor booleano.

    x = True
    y = False
    
    print(x and y)  # False (ambos precisam ser True)
    print(x or y)   # True (pelo menos um é True)
    print(not x)    # False (inverte o valor)
    Python

    Além dos operadores lógicos, Python permite comparações utilizando símbolos como == (igual), != (diferente), > (maior que), < (menor que), >= (maior ou igual) e <= (menor ou igual). Essas operações retornam True ou False, sendo essenciais para a tomada de decisões dentro de um código.

    a = 10
    b = 5
    
    print(a == b)  # False (10 não é igual a 5)
    print(a != b)  # True (10 é diferente de 5)
    print(a > b)   # True (10 é maior que 5)
    print(a <= b)  # False (10 não é menor ou igual a 5)
    Python

    Os booleanos também podem ser usados implicitamente em estruturas condicionais, onde qualquer valor diferente de 0, None, "" (string vazia) ou [] (lista vazia) é considerado True. Isso permite a criação de código mais limpo e intuitivo.

    valor = "Python"
    if valor:  
        print("A string não está vazia!")  
    Python

    Compreender o funcionamento dos booleanos e operações lógicas em Python é essencial para escrever código eficiente e evitar erros comuns em verificações condicionais.

    NoneType no Python

    Em Python, o tipo de dado NoneType representa a ausência de valor e possui um único objeto possível: None. Esse valor especial indica que uma variável não foi inicializada, que uma função não retornou nada explicitamente ou que um objeto esperado não está disponível. O NoneType é amplamente utilizado em verificações condicionais, funções e tratamento de valores nulos, sendo essencial para a manipulação segura de dados em Python.

    valor = None  
    print(valor)  # Saída: None
    print(type(valor))  # Saída: 
    Python

    Uma dúvida comum entre iniciantes é a diferença entre None e False. Embora ambos possam representar estados negativos ou ausentes, eles não são equivalentes. O valor False é um booleano que pode ser usado em operações lógicas, enquanto None representa a ausência de um valor válido. Se compararmos diretamente None == False, o resultado será False, pois são tipos diferentes.

    print(None == False)  # Saída: False
    print(bool(None))  # Saída: False
    Python

    O None é amplamente utilizado em funções que não retornam um valor explícito. Em Python, toda função retorna algo, e caso não haja um return, ela retorna implicitamente None. Esse comportamento é útil para indicar que uma função executou sua lógica sem produzir um valor específico.

    def saudacao(nome):
        if not nome:
            return None
        return f"Olá, {nome}!"
    
    print(saudacao(""))  # Saída: None
    print(saudacao("Maria"))  # Saída: Olá, Maria!
    Python

    Outro uso comum de None está no controle de fluxo e na inicialização de variáveis que serão definidas posteriormente. Isso evita erros ao tentar acessar valores antes de sua definição e permite verificar se um objeto foi alterado ao longo do código.

    resultado = None  # Variável sem valor inicial definido
    
    if resultado is None:
        print("Nenhum resultado ainda!")  
    Python

    O uso correto de None no Python ajuda a escrever código limpo, legível e seguro, prevenindo exceções indesejadas e melhorando a lógica de funções e controle de fluxo.

    Estruturas de Dados Compostas

    Em Python, as estruturas de dados compostas são fundamentais para armazenar e manipular múltiplos valores de maneira eficiente. Cada estrutura — listas, tuplas, dicionários e conjuntos — possui características específicas que as tornam adequadas para diferentes cenários. Compreender quando e como usá-las é essencial para escrever código otimizado e bem estruturado.

    Listas (list) – Armazenando múltiplos valores

    A lista é uma estrutura ordenada e mutável, permitindo a adição, remoção e modificação de elementos. Listas são úteis para armazenar coleções de dados heterogêneos e podem ser manipuladas de diversas formas.

    frutas = ["maçã", "banana", "laranja"]
    frutas.append("uva")  # Adiciona um elemento
    print(frutas[1])  # Acessa o segundo elemento
    Python

    Métodos úteis de listas:

    • .append(elemento): adiciona um item ao final.
    • .remove(elemento): remove a primeira ocorrência de um item.
    • .sort(): ordena os elementos da lista.

    Tuplas (tuple) – Eficiência e Imutabilidade

    As tuplas são semelhantes às listas, mas imutáveis, ou seja, seus valores não podem ser alterados após a criação. Elas são mais eficientes em termos de desempenho e úteis para representar dados que não devem ser modificados.

    cores = ("vermelho", "azul", "verde")
    print(cores[0])  # Acessa o primeiro elemento
    Python

    Vantagens das tuplas:
    ✅ Mais rápidas que listas.
    ✅ São seguras contra alterações acidentais.
    ✅ Ocupam menos espaço na memória.

    Dicionários (dict) – Organização com pares chave-valor

    Os dicionários armazenam dados na forma de pares chave-valor, permitindo acesso rápido às informações associadas a uma chave específica. Eles são muito utilizados para representar objetos estruturados.

    pessoa = {"nome": "Carlos", "idade": 30, "cidade": "São Paulo"}
    print(pessoa["nome"])  # Acessa o valor associado à chave "nome"
    Python

    Métodos úteis:

    • .keys(): retorna todas as chaves.
    • .values(): retorna todos os valores.
    • .items(): retorna pares chave-valor.

    Conjuntos (set) – Coleções sem duplicatas

    Os conjuntos são coleções não ordenadas e sem elementos duplicados, sendo úteis para eliminar valores repetidos ou realizar operações matemáticas como união e interseção.

    numeros = {1, 2, 3, 4, 4, 5}  # O número 4 será armazenado apenas uma vez
    print(numeros)  # Saída: {1, 2, 3, 4, 5}
    Python

    Principais usos dos sets:

    • Remover duplicatas de listas.
    • Testar a existência de um elemento rapidamente.
    • Operações matemáticas como união (|) e interseção (&).

    Escolher a estrutura de dados adequada é crucial para melhorar a performance e legibilidade do código. Saber quando usar listas, tuplas, dicionários e conjuntos ajudará a tornar seu código mais eficiente e organizado.

    Conversão de Tipos (Type Casting)

    Em Python, a conversão de tipos (type casting) é essencial para garantir que os dados sejam manipulados corretamente. Embora a linguagem seja dinamicamente tipada, algumas operações exigem a conversão explícita para evitar erros ou garantir a precisão dos cálculos. Converter entre int, float, str e bool é uma prática comum ao lidar com entrada de usuário, operações matemáticas e manipulação de strings.

    Conversão Explícita entre Tipos

    Python oferece funções para converter tipos de dados de forma direta:

    • int(): converte para número inteiro.
    • float(): converte para ponto flutuante.
    • str(): transforma qualquer valor em string.
    • bool(): converte um valor para True ou False com base em sua existência.

    Exemplo de conversão de str para int e float, útil quando recebemos entrada do usuário:

    idade = input("Digite sua idade: ")  # Retorna uma string
    idade = int(idade)  # Converte para inteiro
    altura = float("1.75")  # Converte para número decimal
    Python

    Quando a Conversão Explícita é Necessária?

    A conversão explícita é essencial quando diferentes tipos de dados precisam interagir, como ao concatenar um número e uma string.

    num = 25
    print("Minha idade é " + str(num))  # Sem str(), geraria um erro
    Python

    Outro cenário comum é converter números para booleanos. Em Python, qualquer valor diferente de zero ou vazio é considerado True, enquanto 0, None e strings vazias são interpretados como False.

    print(bool(0))      # Saída: False
    print(bool(3.14))   # Saída: True
    print(bool(""))     # Saída: False
    print(bool("Python"))  # Saída: True
    Python

    Exemplos Práticos de Conversão

    Caso seja necessário arredondar um valor decimal para um número inteiro, a conversão para int pode ser aplicada.

    valor = 9.99
    preco_final = int(valor)  # Remove a parte decimal
    print(preco_final)  # Saída: 9
    Python

    Outro exemplo prático é converter listas para strings, útil em exibições formatadas:

    nomes = ["Ana", "Carlos", "Beatriz"]
    lista_formatada = ", ".join(nomes)  # Une os nomes em uma string
    print(lista_formatada)  # Saída: Ana, Carlos, Beatriz
    Python

    Dominar type casting permite evitar erros de tipo, melhorar a compatibilidade entre dados e garantir que as operações matemáticas e de manipulação de texto sejam realizadas corretamente.

    https://wordpress.vps9144.panel.icontainer.cloud/dominando-a-automacao-com-python-guia-definitivo-de-respostas-para-todos-os-usuarios-tech/

    Conclusão

    Os tipos de dados em Python são fundamentais para qualquer desenvolvedor que deseja escrever código eficiente, legível e otimizado.

    Ao longo deste guia, exploramos desde os tipos mais básicos, como inteiros (int) e números de ponto flutuante (float), até estruturas mais avançadas, como listas (list), tuplas (tuple), dicionários (dict) e conjuntos (set).

    Compreender quando e como usar cada tipo é essencial para evitar erros, reduzir consumo de memória e melhorar a performance das aplicações.

    Saber escolher o tipo de dado correto não só torna o código mais claro e organizado, mas também facilita a manipulação e armazenamento de informações.

    Por exemplo, enquanto listas são ideais para coleções ordenadas e mutáveis, tuplas oferecem segurança e desempenho quando os dados não precisam ser alterados.

    Já os dicionários são perfeitos para representar estruturas de dados complexas, associando chaves a valores de forma eficiente.

    Aprofundar-se nesse conhecimento permitirá que você desenvolva aplicações mais robustas e evite problemas comuns, como erros de tipo e uso excessivo de memória.

    O próximo passo é explorar estruturas de controle (if, for, while), tratamento de exceções e a orientação a objetos, tornando seu código ainda mais estruturado e profissional.

    Se você deseja continuar aprendendo Python de forma gratuita, recomendamos este excelente material: Curso gratuito de Python. Nele, você encontrará tutoriais e conteúdos para aprofundar ainda mais seus conhecimentos e dominar a linguagem.

    E tambem a documentação oficial do python em https://www.python.org/doc/.

  • Fundamentos Do Python | Postagem 1

    Fundamentos Do Python | Postagem 1

    O Python é uma das linguagens de programação mais populares do mundo. Criado por Guido van Rossum no início dos anos 90, o Python se destaca por sua sintaxe simples, legibilidade e versatilidade. Sua curva de aprendizado suave o torna ideal tanto para iniciantes quanto para desenvolvedores experientes. Com uma vasta comunidade ativa e uma enorme quantidade de bibliotecas disponíveis, Python é amplamente utilizado em diversas áreas da tecnologia.

    Aprender os fundamentos do Python é essencial para quem deseja ingressar no mundo da programação. A linguagem é frequentemente recomendada para iniciantes devido à sua estrutura intuitiva e ao fato de ser uma linguagem interpretada, permitindo a execução de código linha por linha. Isso facilita testes rápidos e torna o processo de aprendizado mais dinâmico. Além disso, dominar os princípios básicos do Python abre portas para áreas avançadas, como desenvolvimento web, ciência de dados, automação de tarefas e inteligência artificial.

    As aplicações do Python são vastas e cobrem diversos setores da indústria. Ele é amplamente utilizado em desenvolvimento de software, análise de dados, machine learning, cibersegurança, automação de processos e até mesmo no desenvolvimento de aplicações web e APIs. Empresas como Google, Facebook, Netflix e Amazon utilizam Python para otimizar seus serviços e criar soluções escaláveis. A linguagem também é a base para ferramentas de automação, como web scraping e bots para redes sociais.

    Se você está começando agora, aprender os fundamentos do Python será um grande diferencial. O conhecimento da sintaxe básica, estrutura de controle de fluxo e manipulação de dados permitirá que você desenvolva projetos práticos desde os primeiros passos. Seja criando um simples script de automação ou desenvolvendo um modelo de machine learning, Python oferece um ecossistema rico para explorar e crescer como programador.

    Instalando e Configurando o Python

    Para começar a programar com Python, é essencial instalar a linguagem corretamente no seu sistema operacional. O Python é compatível com Windows, Linux e macOS, e sua instalação é relativamente simples. A versão mais recomendada é a Python 3, pois o Python 2 já não recebe mais suporte oficial. Antes de prosseguir, verifique se o Python já está instalado no seu computador, pois alguns sistemas, como o macOS e certas distribuições Linux, já incluem a linguagem por padrão.

    Instalando o Python no Windows

    No Windows, o primeiro passo é baixar o instalador do Python diretamente do site oficial:

    ➡ Acesse: https://www.python.org/downloads/

    Após o download, execute o arquivo .exe e marque a opção “Add Python to PATH”, garantindo que o Python possa ser acessado via prompt de comando (cmd). Em seguida, clique em “Install Now” e aguarde a instalação. Para testar se tudo foi instalado corretamente, abra o terminal e digite:

    python --version
    Bash

    Se o terminal exibir algo como Python 3.x.x, significa que a instalação foi concluída com sucesso.

    Instalando o Python no Linux

    A maioria das distribuições Linux, como Ubuntu e Debian, já vêm com o Python pré-instalado. Para verificar a versão disponível, basta rodar:

    python --version
    Bash

    Caso o Python não esteja instalado ou precise ser atualizado, use o seguinte comando:

    sudo apt update && sudo apt install python3 -y
    Bash

    Para distribuições Fedora ou CentOS, utilize:

    sudo dnf install python3
    Bash

    Instalando o Python no macOS

    No macOS, o Python também pode estar pré-instalado, mas pode ser necessário instalar a versão mais recente. O método mais simples é utilizar o Homebrew, um gerenciador de pacotes eficiente:

    brew install python
    Bash

    Após a instalação, verifique a versão com:

    python3 --version
    Bash

    Com o Python instalado corretamente, o próximo passo é configurar um ambiente de desenvolvimento adequado para começar a escrever código de forma eficiente.

    Executando Código Python

    Depois de instalar e configurar o Python, o próximo passo é aprender a executar código de diferentes formas. O Python pode ser rodado diretamente no terminal, através de scripts .py, ou em notebooks Jupyter, dependendo da necessidade do projeto. Entender essas abordagens permitirá que você escolha a melhor opção para cada situação.

    Rodando Código no Terminal

    A maneira mais rápida de testar um comando em Python é utilizando o interpretador interativo no terminal. Para abrir o modo interativo, basta digitar python ou python3 no terminal:

    python3
    Bash

    Isso abrirá um ambiente onde você pode executar comandos linha por linha. Por exemplo:

    >> 1 + 2
    3
    Bash

    Para sair do modo interativo, basta digitar exit() e pressionar Enter. Esse método é ideal para testes rápidos e para entender a execução de pequenos trechos de código.

    Criando e Executando Scripts .py

    Em projetos mais estruturados, o código Python é geralmente salvo em arquivos com extensão .py. Para criar um script, basta abrir um editor de texto ou IDE, escrever o código e salvar o arquivo, por exemplo, como meu_script.py. Veja um exemplo simples de script:

    # Exemplo de script Python
    nome = input("Digite seu nome: ")
    print(f"Olá, {nome}! Bem-vindo ao Python.")
    Python

    Para rodar esse script no terminal, navegue até a pasta onde ele está salvo e execute:

    python3 meu_script.py
    Bash

    Esse método permite criar programas mais elaborados, armazenar lógicas complexas e reutilizar código em diferentes execuções.

    Usando Notebooks Jupyter

    O Jupyter Notebook é uma ferramenta interativa amplamente utilizada em ciência de dados, aprendizado de máquina e análise exploratória. Ele permite a execução de código em células individuais, facilitando a visualização de saídas e a inclusão de explicações em formato de texto.

    Para instalar o Jupyter Notebook, utilize o pip:

    pip install notebook
    Bash

    Após a instalação, execute o seguinte comando para abrir o ambiente:

    jupyter notebook
    Bash

    Isso abrirá uma interface web onde você pode criar e executar código interativamente. No Jupyter Notebook, o código pode ser executado célula por célula, permitindo experimentação rápida e organização mais clara dos blocos de código.

    Cada método de execução do Python tem suas vantagens. O terminal é ideal para testes simples, os scripts .py são perfeitos para projetos estruturados, e os Jupyter Notebooks são indispensáveis para análise de dados e aprendizado interativo. Conhecendo essas opções, você pode escolher a abordagem mais eficiente para cada necessidade.

    Primeiros Passos com Python

    Agora que o Python está instalado e você sabe como executar código, é hora de dar os primeiros passos com a linguagem. Vamos começar com o clássico “Olá, Mundo!”, aprender sobre variáveis e explorar operações matemáticas e lógicas.

    Escrevendo e Executando Seu Primeiro Programa

    Todo programador começa aprendendo a exibir uma mensagem na tela. No Python, isso é feito com a função print(). Crie um novo arquivo chamado primeiro_programa.py e adicione o seguinte código:

    print("Olá, Mundo!")
    Python

    Para rodar o script, basta executar no terminal:

    python3 primeiro_programa.py
    Bash

    Se tudo estiver correto, a mensagem “Olá, Mundo!” será exibida no terminal. Esse simples comando já mostra como o Python pode ser usado para interagir com o usuário.

    https://wordpress.vps9144.panel.icontainer.cloud/dominando-a-automacao-com-python-guia-definitivo-de-respostas-para-todos-os-usuarios-tech/

    Trabalhando com Variáveis e Tipos de Dados

    No Python, variáveis são usadas para armazenar valores, como números e textos. Os principais tipos de dados são:

    Tipo de DadoExemploDescrição
    String"Python"Texto entre aspas.
    Inteiro10Número sem casas decimais.
    Float3.14Número com ponto decimal.
    BooleanoTrue, FalseRepresenta verdadeiro ou falso.

    Exemplo de uso de variáveis:

    nome = "Alice"  # String
    idade = 25  # Inteiro
    altura = 1.65  # Float
    estudante = True  # Booleano
    
    print(f"Nome: {nome}, Idade: {idade}, Altura: {altura}, Estudante: {estudante}")
    Python

    Operadores Matemáticos e Lógicos

    O Python suporta operações matemáticas básicas, como adição, subtração, multiplicação e divisão, além de operadores lógicos para tomadas de decisão.

    Operações matemáticas:

    a = 10
    b = 3
    
    soma = a + b       # Adição
    subtracao = a - b  # Subtração
    multiplicacao = a * b  # Multiplicação
    divisao = a / b    # Divisão (float)
    divisao_inteira = a // b  # Divisão inteira
    resto = a % b      # Módulo (resto da divisão)
    
    print(soma, subtracao, multiplicacao, divisao, divisao_inteira, resto)
    Python

    Operadores lógicos:

    x = 5
    y = 10
    
    print(x > y)  # Maior que
    print(x < y)  # Menor que
    print(x == y)  # Igualdade
    print(x != y)  # Diferente
    Python

    Esses conceitos básicos são essenciais para qualquer aplicação em Python. Com essa base, você já pode começar a explorar estruturas mais avançadas, como condicionais e loops, para criar programas mais interativos e dinâmicos.

    Estruturas de Controle no Python

    As estruturas de controle são fundamentais na programação, pois permitem a tomada de decisões e a repetição de comandos de forma eficiente. No Python, utilizamos condicionais para executar blocos de código apenas se certas condições forem atendidas, e loops para repetir ações automaticamente.

    Condicionais: if, elif e else

    A estrutura condicional if-elif-else permite executar blocos de código diferentes dependendo de uma condição.

    idade = 18
    
    if idade < 18:
        print("Você é menor de idade.")
    elif idade == 18:
        print("Você acabou de atingir a maioridade!")
    else:
        print("Você é maior de idade.")
    Python

    No exemplo acima, o Python verifica a idade e escolhe o bloco de código adequado. O if testa a primeira condição, o elif adiciona novas verificações e o else cobre todos os outros casos.

    Laços de Repetição: for e while

    Os loops permitem executar um bloco de código múltiplas vezes. O for é usado quando sabemos quantas vezes devemos repetir, enquanto o while continua a execução até que uma condição seja falsa.

    Exemplo com for (iterando sobre uma lista):

    frutas = ["maçã", "banana", "uva"]
    
    for fruta in frutas:
        print(f"Eu gosto de {fruta}")
    Python

    Exemplo com while (repetindo enquanto uma condição for verdadeira):

    contador = 0
    
    while contador < 5:
        print(f"Contagem: {contador}")
        contador += 1
    Python

    Uso do break e continue

    Os comandos break e continue permitem um controle mais refinado dos loops.

    • break encerra um loop antes do esperado.
    • continue pula a iteração atual e avança para a próxima.
    for numero in range(10):
        if numero == 5:
            break  # Para a execução quando o número for 5
        print(numero)
    Python
    for numero in range(10):
        if numero % 2 == 0:
            continue  # Pula os números pares
        print(numero)
    Python

    Com essas estruturas, você pode criar programas mais dinâmicos e interativos. Nos próximos tópicos, exploraremos estruturas de dados e como manipular coleções de forma eficiente.

    Funções e Módulos no Python

    Uma das características mais poderosas do Python é a possibilidade de reutilizar código por meio de funções e módulos. Funções permitem organizar o código em blocos reutilizáveis, enquanto os módulos possibilitam a importação de funcionalidades prontas para uso.

    Criando Funções com def

    No Python, funções são definidas com a palavra-chave def. Elas ajudam a tornar o código mais organizado e evitam repetições desnecessárias.

    def saudacao():
        print("Olá, seja bem-vindo ao Python!")
    
    saudacao()
    Python

    A função acima imprime uma mensagem sempre que for chamada. Para criar funções mais flexíveis, podemos utilizar parâmetros.

    Parâmetros e Retorno de Funções

    Parâmetros permitem que a função receba valores externos. O retorno (return) permite que uma função envie um resultado para quem a chamou.

    def soma(a, b):
        return a + b
    
    resultado = soma(5, 3)
    print(f"A soma é: {resultado}")
    Python

    Aqui, soma(5, 3) retorna 8, pois passamos 5 e 3 como argumentos.

    Importação de Módulos e Bibliotecas Nativas

    O Python possui diversos módulos embutidos que oferecem funcionalidades avançadas sem necessidade de instalação. Para usá-los, basta importar com import.

    import math
    
    raiz = math.sqrt(16)
    print(f"A raiz quadrada de 16 é {raiz}")
    Python
    import math
    
    raiz = math.sqrt(16)
    print(f"A raiz quadrada de 16 é {raiz}")
    Python

    Também é possível importar funções específicas de um módulo:

    from math import sqrt
    
    print(sqrt(25))  # Retorna 5.0
    Python

    Além dos módulos embutidos, podemos instalar bibliotecas externas, como NumPy, Pandas e Requests, para ampliar as funcionalidades do Python. Dominar funções e módulos é essencial para escrever códigos mais organizados e eficientes.

    Trabalhando com Listas e Dicionários no Python

    No Python, listas e dicionários são estruturas de dados fundamentais para armazenar e manipular informações. As listas permitem armazenar coleções ordenadas de elementos, enquanto os dicionários utilizam o formato chave-valor para um acesso mais eficiente aos dados.

    Criando e Manipulando Listas

    Uma lista é uma estrutura ordenada que pode conter diferentes tipos de dados, como inteiros, strings e até outras listas.

    frutas = ["maçã", "banana", "laranja"]
    print(frutas)  # Saída: ['maçã', 'banana', 'laranja']
    Python

    Para modificar listas, podemos utilizar métodos como append, remove e len.

    frutas.append("uva")  # Adiciona "uva" à lista
    frutas.remove("banana")  # Remove "banana"
    tamanho = len(frutas)  # Retorna o número de elementos na lista
    print(frutas, tamanho)  
    Python

    Também podemos acessar elementos individuais e fazer slicing, que permite obter partes específicas da lista.

    print(frutas[0])  # Primeiro elemento
    print(frutas[-1])  # Último elemento
    print(frutas[1:3])  # Do segundo ao terceiro elemento
    Python

    Trabalhando com Dicionários (Chave-Valor)

    Os dicionários são coleções não ordenadas que armazenam pares de chave-valor, permitindo acesso rápido aos dados.

    dados_pessoa = {"nome": "Carlos", "idade": 30, "cidade": "São Paulo"}
    print(dados_pessoa["nome"])  # Acesso pelo nome da chave
    Python

    Podemos adicionar, atualizar e remover elementos em um dicionário.

    dados_pessoa["profissão"] = "Engenheiro"  # Adiciona uma nova chave
    dados_pessoa["idade"] = 31  # Atualiza um valor
    del dados_pessoa["cidade"]  # Remove um item
    print(dados_pessoa)
    Python

    Listas e dicionários são amplamente usados na programação em Python, desde manipulação de dados até aplicações mais complexas como machine learning e desenvolvimento web. Dominar essas estruturas é essencial para escrever códigos eficientes e bem organizados.

    Manipulação de Arquivos no Python

    Manipular arquivos é uma habilidade essencial para qualquer desenvolvedor Python. A linguagem oferece suporte para ler, escrever e modificar arquivos de diferentes formatos, como TXT e JSON, permitindo o armazenamento e recuperação eficiente de informações.

    Lendo e Escrevendo Arquivos .txt

    Para trabalhar com arquivos de texto no Python, utilizamos a função open(), que nos permite abrir um arquivo em diferentes modos:

    • r → leitura (read)
    • w → escrita (write) (substitui o conteúdo existente)
    • a → escrita em modo de adição (append)
    • r+ → leitura e escrita (read & write)

    Exemplo de Escrita em Arquivo

    with open("arquivo.txt", "w") as arquivo:
        arquivo.write("Olá, mundo!\nEste é um arquivo de texto.")
    Python

    O uso da instrução with garante que o arquivo seja fechado corretamente após a execução.

    Exemplo de Leitura de Arquivo

    with open("arquivo.txt", "r") as arquivo:
        conteudo = arquivo.read()
        print(conteudo)
    Python

    Trabalhando com Arquivos JSON

    Os arquivos JSON (JavaScript Object Notation) são amplamente utilizados para armazenar e trocar dados estruturados entre aplicações, pois seguem um formato leve e legível. No Python, a biblioteca json facilita a conversão de dicionários para arquivos JSON e vice-versa.

    Salvando um Dicionário como JSON

    import json
    
    dados = {"nome": "Alice", "idade": 25, "cidade": "Rio de Janeiro"}
    
    with open("dados.json", "w") as arquivo_json:
        json.dump(dados, arquivo_json, indent=4)
    Python

    Lendo um Arquivo JSON

    with open("dados.json", "r") as arquivo_json:
        dados_carregados = json.load(arquivo_json)
        print(dados_carregados)
    Python

    A manipulação de arquivos em Python é fundamental para armazenamento de logs, configuração de sistemas, troca de dados entre APIs e até mesmo análise de grandes volumes de informação. Dominar esse conceito amplia as possibilidades de automação e integração de sistemas.

    Erros e Exceções no Python

    No desenvolvimento de software, erros e exceções são inevitáveis. Em Python, quando ocorre um erro durante a execução do código, a linguagem gera uma exceção, interrompendo o fluxo normal do programa. Para garantir um funcionamento mais estável, é essencial saber como identificar, tratar e evitar exceções.

    Tratamento de Erros com try e except

    O Python oferece a estrutura try-except para capturar e tratar erros sem que o programa pare inesperadamente. O bloco try contém o código que pode gerar um erro, enquanto o except define a ação a ser tomada caso um erro ocorra.

    Exemplo de Tratamento de Exceções

    try:
        numero = int(input("Digite um número: "))
        print(f"O dobro de {numero} é {numero * 2}")
    except ValueError:
        print("Erro: Você deve digitar um número válido.")
    Python

    Se o usuário digitar algo que não seja um número, o except ValueError será acionado, evitando que o programa pare abruptamente.

    Principais Exceções em Python e Como Evitá-las

    Abaixo estão algumas exceções comuns e como preveni-las:

    ExceçãoOcorre Quando…Como Evitar
    ValueErrorConversão inválida de tipo de dadoValidar entrada antes da conversão
    ZeroDivisionErrorDivisão por zeroVerificar divisor antes da operação
    IndexErrorÍndice fora do alcance em listasGarantir que o índice existe
    KeyErrorChave inexistente em um dicionárioUsar .get() para evitar erro
    TypeErrorOperação entre tipos incompatíveisVerificar tipos antes de operações

    Exemplo de try-except com múltiplas exceções

    try:
        lista = [1, 2, 3]
        print(lista[5])  # Tentando acessar um índice inexistente
    except IndexError:
        print("Erro: Índice fora do alcance da lista.")
    except Exception as e:
        print(f"Ocorreu um erro inesperado: {e}")
    Python

    Utilizar tratamento de exceções melhora a robustez do código, prevenindo falhas inesperadas e oferecendo uma melhor experiência ao usuário. O uso adequado do try-except também facilita a depuração, tornando o código mais seguro e confiável.

    Próximos Passos no Aprendizado de Python

    Após dominar os conceitos básicos de Python, é essencial continuar praticando para aprimorar suas habilidades. A melhor forma de consolidar o aprendizado é explorar recursos educativos de qualidade e aplicar os conhecimentos adquiridos em projetos práticos.

    Onde Aprender Mais Sobre os Fundamentos do Python

    Para quem deseja aprofundar-se na linguagem, existem diversas opções de cursos online, tutoriais e documentações oficiais. O curso gratuito de Python da ProSimples (acesse aqui) é uma excelente opção para quem busca conteúdo estruturado e de fácil compreensão. Além disso, a documentação oficial do Python (docs.python.org) fornece materiais detalhados para consultas rápidas.

    Recursos Gratuitos e Cursos Recomendados

    Aqui estão alguns dos melhores recursos gratuitos para aprender Python:

    Projetos Simples para Praticar

    A melhor forma de fixar os conceitos aprendidos é criando projetos práticos. Aqui estão algumas ideias para iniciantes:

    1. Calculadora Simples – Um programa que realiza operações matemáticas básicas.
    2. Lista de Tarefas (To-Do List) – Aplicação que permite adicionar, remover e listar tarefas.
    3. Jogo de Adivinhação – O usuário tenta adivinhar um número gerado aleatoriamente.
    4. Conversor de Moedas – Programa que converte valores entre diferentes moedas usando uma API.
    5. Gerador de Senhas – Aplicação que cria senhas aleatórias seguras.

    Com dedicação e prática, é possível se tornar proficiente em Python e avançar para áreas como desenvolvimento web, automação, análise de dados e inteligência artificial. O aprendizado contínuo é a chave para o sucesso na programação!

  • Como Criar Um App Todo Com Django

    Como Criar Um App Todo Com Django

    Nesta postagem, quero mostrar a criação de um aplicativo simples (app To-Do) usando Django. No entanto, meu objetivo é aprofundar os detalhes deste tutorial para que você possa praticar e aprender de verdade todo o básico desse poderoso framework Python.

    Com isso, você aprenderá a iniciar um projeto Django, entendendo sua estrutura básica de arquivos. Além disso, veremos como criar templates e trabalhar com hierarquia de templates. Também utilizaremos os models do Django para persistir os dados no banco de dados SQLite3.

    Outro ponto importante que quero destacar é que, neste tutorial, focaremos no uso de classes para as views (as famosas CBVs – Class-Based Views) em vez de funções simples, aproveitando melhor os recursos do Django.

    Portanto, se você acompanhar este tutorial até o final, tenho plena certeza de que irá expandir significativamente seu conhecimento no Django.

    Imagem do que iremos criar com django?

    Neste tutorial, vamos desenvolver exatamente o que está na imagem abaixo: um aplicativo simples chamado “My ToDo”.

    Ele contará com um formulário de um único campo para adicionar a descrição do to-do, um botão para adicionar tarefas, além de uma listagem com ícones para marcar tarefas como concluídas. Logo abaixo, também teremos uma paginação para navegar entre as tarefas cadastradas.

    Alem disso, neste tutorial irei fazer o meu melhor para que voce receba gratificação de criação e aprendizado, não apenas ficar criando o codigo.

    Por isso, iremos iniciar o projeto com o setup do código e ja iremos construir o frontend com as templates e CSS. Para depois criarmos as funcionalidades com as views e a model, blz?

    Iniciando o projeto

    Antes de iniciarmos o projeto, e excencial que você tenha um lugar onde ira criar este projeto. Eu te indico criar uma nova pasta chamada django_todo. Onde iremos entrar nesta pasta e adicionar todo o nosso código.

    Então vamos la…

    Passo 1: Crie uma nova pasta chamada django_todo

    $ % mkdir django_todo
    $ % cd django_todo
    Bash

    Ja na pasta todo_app iniciaremos a criação do setup do projeto.

    Passo 2: Instale o ambiente virtual python

    Nesta etapa, ja dentro da pasta django_todo é hora de criar o ambiente virtual para que possamos isolar a nossa aplicação do ambiente padrão python do computador.

    $ django_todo % python3 -m venv venv
    $ django_todo % source venv/bin/activate # venv\Scripts\actvate para o windows
    Bash

    Ja com a instalação do ambiente virtual criado e ativado na pasta django_todo, é hora de instalar o django.

    Passo 3: Instalação do django e setup inicial do projeto

    Com o ambiente virtual instalado é hora de instalar o pacote django usando o pip (gerenciador de pacotes do python).

    $ (venv) django_todo % pip install django
    Bash

    Depois de instalar o django você estará pronto para usar a interface de administracao automatica do django django-admin para criar novos apps, projetos, migrar tabelas e rodar o servidor.

    Então vamos lá. Vamos iniciar um novo projeto dentro da pasta que voce acabou de criar e também criar um novo app onde iremos adicionar a maioria do código desta aplicação.

    $ (venv) django_todo % django-admin startproject todo_project .
    Bash

    Com o comando acima você criou uma nova pasta chamada todo_project. No qual será a parte principal do nosso projeto, com arquivos como: url.py, asgi.py, wsgi.py e settings.py. E junto com esta pasta, também na raiz do projéto, um arquivo chamado manage.py. Que também tem o proposito de interface de administracao automatica.

    Ágora que criamos o arquivo do projeto, é hora de criarmos o app que falei anteriormente.

    PS: Voce pode usar tanto o django-admin quanto o manage.py porém terá que adicionar o python antes.

    Para náo confundir você irei continuar usando o django-admin….

    $ (venv) django_todo % django-admin startapp todo_app
    Bash

    Ágora que você já criou a pasta do projeto e a pasta do aplicativo onde nós iremos adicionar nosso código, e assim que deve parecer o seu diretório:

    django_todo/
    ├── venv/                    # Ambiente virtual (não incluído no controle de versão)
    ├── todo_project/            # Pasta do projeto Django
    │   ├── __init__.py          # Arquivo que indica que esta pasta é um pacote Python
    │   ├── asgi.py              # Configuração ASGI para deploy
    │   ├── settings.py          # Configurações do projeto Django
    │   ├── urls.py              # URLs principais do projeto
    │   ├── wsgi.py              # Configuração WSGI para deploy
    │   └── __pycache__/         # Pasta de cache Python (gerada automaticamente)
    ├── todo_app/                # Pasta do app "todo_app"
    │   ├── migrations/          # Pasta para armazenar migrações do banco de dados
    │   │   └── __init__.py      # Arquivo que indica que esta pasta é um pacote Python
    │   ├── __init__.py          # Arquivo que indica que esta pasta é um pacote Python
    │   ├── admin.py             # Configuração do painel de administração do Django
    │   ├── apps.py              # Configuração do app
    │   ├── models.py            # Definição dos modelos do banco de dados
    │   ├── tests.py             # Testes unitários do app
    │   ├── views.py             # Lógica de visualização do app
    │   └── __pycache__/         # Pasta de cache Python (gerada automaticamente)
    ├── manage.py                # Script de gerenciamento do Django
    Bash

    Tirando a pasta django_todo/ todos os arquivos dentro deste diretórios foram criados usando os comandos usados acima.

    Tanto para a criacao do projeto quanto para a criação do app. Agora, cheque bem e veja se esta igual ao diretório de pastas que você tem em sua aplicação.

    Passo 4: Conexão do aplicativo todo_app com o projeto todo_project

    Ágora que já criamos todas as partes iniciais do projeto é hora de conectar o todo_app no todo_project para que ele seja reconhecido pelo django.

    Para isso você terá que ir no arquivo settings.py e adicionar o nome desta pasta como string na constante INSTALLED_APPS.

    # todo_project/settings.py
    
    # mais codigo acima...
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'todo_app', # <-- Adicione esta linha.
    ]
    
    # mais codigo abaixo...
    Python

    Perfeito. Agora estamos prontos para irmos para o próximo passo.

    Passo 5: Criação da template base do projeto

    Como o app ja esta conectado com o projeto, precisamos criar a template principal (base) que irá receber as outras templates. Porém, iremos inicialmente criar o html nela para que você veja o frontend da aplicacão ja pronto antes de criarmos as funcionalidades com o django.

    Para isso, você precisa criar uma nova pasta dentro do app todo_app chamada templates. Esta pasta sera responsável pela alocação de todas as templates (arquivos html) deste applicativo do projeto.

    E dentro da pasta templates adicione um novo arquivo html chamado base.html no qual iremos adicionar o codigo html inicial do projeto.

    Caso você criou corretamente a pasta templates dentro do app todo_app e também criou um novo arquivo html chamado, base.html dentro da pasta templates, o seu diretório deverá estar desta maneira:

    django_todo/
    ├── venv/                    
    ├── todo_project/            
    │   ├── __init__.py          
    │   ├── asgi.py              
    │   ├── settings.py          
    │   ├── urls.py              
    │   ├── wsgi.py              
    │   └── __pycache__/         
    ├── todo_app/                
    │   ├── migrations/          
    │   │   └── __init__.py      
    │   ├── templates/           # <-- Pasta para armazenar os templates do app
    │   │   ├── base.html        # <-- Template base para herança nos outros templates
    │   ├── __init__.py          
    │   ├── admin.py             
    │   ├── apps.py              
    │   ├── models.py            
    │   ├── tests.py             
    │   ├── views.py             
    │   └── __pycache__/         
    Bash

    Ágora que você tem o arquivo base.html no seu projeto, você pode ja adicionar o código html nele. Porém, ainda não iremos rodar o projeto beleza?

    
    
    {% load static %}
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="{% static 'css/style.css' %}">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/fontawesome.min.css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/all.min.css">
        <title>My ToDotitle>
    head>
    <body>
        <div class="header-container">
            <h1>My Todoh1>
        div>
    
        <div class="main-container">
            <form method="post" class="todo-form">
                <input type="text" class="input-form" placeholder="Add a new todo...">
                <button class="submit-button">Add Todobutton>
            form>
            
            <ul class="main-list-container">
                <li class="list">
                    Buy groceries
                    <div class="icons">
                        <a href="#"><i class="far fa-square">i>a>
                    div>
                li>
                <li class="list gray-background-two">
                    Complete project report
                    <div class="icons">
                        <a href="#"><i class="far fa-check-square">i>a>
                    div>
                li>
                <li class="list">
                    Call mom
                    <div class="icons">
                        <a href="#"><i class="far fa-square">i>a>
                    div>
                li>
                <li class="list">
                    Workout for 30 minutes
                    <div class="icons">
                        <a href="#"><i class="far fa-square">i>a>
                    div>
                li>
                <li class="list gray-background-two">
                    Read 10 pages of a book
                    <div class="icons">
                        <a href="#"><i class="far fa-check-square">i>a>
                    div>
                li>
            ul>
        div>
    
        <div class="pagination">
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-left">i>
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-left">i> 
            a>
    
            <span class="pagination-current">Page 1 of 3span>
    
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-right">i> 
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-right">i> 
            a>
        div>
    body>
    html>
    HTML

    Passo 6: Criando a pasta static para adição do arquivo de css

    Como você tem o código html no projeto, você precisa adicionar o css para criar estilos na página. Com isso, você seguirá o mesmo passo que fez para adicionar a pasta templates no projeto. Criando uma nova pasta chamada static dentro do todo_app também.

    Com a pasta static criada você precisa criar uma sub-pasta dentro da pasta static chamada css no qual será usada para adicionar nosso arquivo style.css. Resumindo esta e a sequência que você deve criar dentro da pasta todo_app:

    (a) static -> (b) css -> (c) style.css

    Com isso, caso você fez corretamente a criação irá ficar desta maneira seu diretorio:

    django_todo/
    ├── venv/                    
    ├── todo_project/            
    │   ├── __init__.py          
    │   ├── asgi.py              
    │   ├── settings.py          
    │   ├── urls.py              
    │   ├── wsgi.py              
    │   └── __pycache__/         
    ├── todo_app/                
    │   ├── migrations/          
    │   │   └── __init__.py      
    │   ├── templates/           
    │   │   ├── base.html        
    │   ├── static/              # <-- Pasta para arquivos estáticos (CSS, JS, imagens)
    │   │   ├── css/             # <-- Sub-pasta para armazenar arquivos CSS
    │   │   │   ├── style.css    # <-- Arquivo de estilos CSS
    │   ├── __init__.py          
    │   ├── admin.py             
    │   ├── apps.py              
    │   ├── models.py            
    │   ├── tests.py             
    │   ├── views.py             
    │   └── __pycache__/         
    Bash

    Ágora, dentro do arquivo style.css, você terá que adicionar todo o codigo css que irei deixar abaixo.

    Neste tutorial, não irei focar no css em questão. Pois, acredito que tiraria boa parte do tutorial do projeto apenas explicando cada detalhe de cada classe e propriedade do css.

    E este não é o foco neste momento. Porém, isso não te impede de dar uma olhada da maneira que cada classe e elemento do html e estilizado com o CSS.

    /* todo_app/static/css/style.css */
    
    * {
        font-family: Arial, Helvetica, sans-serif;
    }
    
    body {
        margin: 0;
        padding: 0;
    }
    
    ul {
        list-style: none; /* Removes bullet points */
        margin: 0; /* Removes default margins */
        padding: 0; /* Removes default padding */
    }
    
    .header-container {
        display: flex;
        align-items: center;
        height: 50px;
        border-bottom: 1px solid #cecece;
        padding: 0 20px 0 20px;
    }
    
    .header-container h1 {
        font-size: x-large;
        color: #7634d9;
        font-weight: 900;
    }
    
    
    .main-container {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
    }
    
    .todo-form {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
    }
    
    .input-form {
        height: 50px;
        width: 45%;
        margin: 20px 0;
        
        /* Ensure uniform border */
        border: 2px solid #cecece;  
        border-radius: 10px;
    
        /* Optional: Improve input focus */
        outline: none;
        padding: 0 20px;
        box-sizing: border-box;
    
    }
    
    .input-form:focus {
        border-color: #888; /* Um pouco mais escuro quando clicado */
    }
    
    button.submit-button {
        width: 15%;
        height: 50px;
        border-radius: 10px;
        background-color: #7634d9;
        border-color: #7634d9;
        margin-left: 5px;
        color: white;
        font-weight: 700;
        font-size: large;
    }
    
    ul.main-list-container {
        display: flex;
        margin: 0;
        width: 60%;
        flex-direction: column;
        align-items: center;
    }
    
    .main-list-container li.list {
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 80px;
        width: 100%;
        border: 2px solid #cecece;
        border-radius: 10px;
        margin-top: 5px;
        padding: 0 20px;
        box-sizing: border-box; /* Evita o container crescer com o padding.*/
        font-size: x-large;
    }
    
    .main-list-container li.list.gray-background{
        background-color: #cecece;
    }
    
    .gray-background-two {
        background-color: #e3e3e3;
    }
    
    .far.fa-square, 
    .far.fa-check-square{
        margin-right: 10px;
        color: #7634d9;
    }
    
    .pagination {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 70px;
    }
    
    .pagination-link {
        margin:0 10px;
    }
    CSS

    Passo 7: Criação da view e url para renderizar a template

    Já que ágora todo o código inicial ja foi adicionado, é hora de criarmos uma view para renderizar nossa template ao rodarmos na aplicação de afazeres (to-do). Caso você seja novo no django, entenda que e necessário termos uma view (função ou classe) no qual irá gerenciar as requisições na nossa pagina através de uma url.

    Nesse caso, a view será responsável de:

    • Receber a requisição da url.
    • Entender qual a template que é responsável por esta requisição.
    • E enviar uma resposta (como um código html) para sua tela (cliente).
    # todo_app/views.py
    
    from django.views.generic import TemplateView
    
    class TodoListView(TemplateView):
        template_name = 'base.html'
    Python

    No código acima temos uma view chamada TodoListView no arquivo views.py, que ira ser adicionada na url, com uma classe genérica chamada TemplateView que é simplesmente usada para renderizar templates. E também uma variavel padrão esperada com o nome template_name apontando para a ‘base.html’ que criamos anteriormente.

    Sendo assim, se você estiver se perguntando:

    — Como que o django sabe que existe a template apenas pelo nome da template em string?

    De uma olhada no settings.py, lá temos uma configuração de uma constante chamada TEMPLATES no qual configura todos esses caminhos.

    Já que adicionamos a view, é hora de adicionarmos a url no qual irá apontar para view que ira retornar o html da template.

    # todo_app/urls.py
    
    from django.contrib import admin
    from django.urls import path
    from .views import TodoListView
    
    urlpatterns = [
        path('', TodoListView.as_view(), name='todo-list'),
    ]
    Python

    Na url.py adicionamos uma view que está mapeada para retornar sua resposta no root de nossa url. Ou seja, essa view irá ser retornada sem precisar ser adicionado nenhum parametro na url. Por isso a string vazia logo no inicio: path(‘‘, …resto do codigo…).

    Passo 8: Rodando a aplicação com código inicial

    Agora que você já adicionou toda a configuração inicial é hora de rodarmos nossa aplicação. No terminal do projeto adicione o seguinte comando para que o servidor de desenvolvimento do django se inicie:

    $ (venv) django_todo % python manage.py runserver
    Bash

    E caso toda a configuração que você fez anteriormente funcionar ésta é a mensagem que você receberá logo em seguida:

    $ (venv) django_todo % python manage.py runserver
    Watching for file changes with StatReloader
    Performing system checks...
    
    System check identified no issues (0 silenced).
    February 16, 2025 - 17:42:35
    Django version 5.1.6, using settings 'todo_project.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CONTROL-C.
    Bash

    Copie o caminho passado pelo servidor do django em uma url do seu browser:

    • http://127.0.0.1:8000/

    Caso tudo foi adicionado corretamente esta e a tela que voce ira receber:

    Clique Rerun caso a tela fique branca… e coloque no tamanho 0.5x para ver com tamanho proximo do real.

    Você percebe que temos nesta tela, um formulario unico para adicionarmos um to-do com um botão escrito (Add Todo)? Também, uma listagem de afazeres com a descrição a esquerda, e um checkbox na direita, onde alguns estao checados enquanto outros estao vazios?

    E logo abaixo temos um sistema simples de paginacao (sem muito stilo css) no qual logo a mais nesta postagem iremos configura-lo para percorremos a lista de afazeres de cinco-em-cinco.

    Porém, neste momento não temos nenhuma funcionalidade apenas um site estatico.

    Passo 9: Criando o models para persistimos dados na aplicação

    Ja que temos nossa aplicação configurado e o frontend ja desenvolvido é hora de criarmos o núcleo de nossa aplicação em termos de funcionalidades:

    O modelo Todo para persistimos os dados.

    Com isso, você precisará abrir o arquivo models.py no todo_app e adicionar o código a seguir que representa a tabela onde iram ser inseridos os afazeres, ou to-dos.

    # todo_app/models.py
    
    from django.db import models
    
    # Create your models here.
    class Todo(models.Model):
        description = models.CharField(max_length=200)
        is_done = models.BooleanField(default=False)
    
        def __str__(self):
            return str(self.description)
    Python

    No código acima, criamos o modelo chamado Todo no qual terá duas colunas:

    1. description: com o tipo de campo string.
    2. is_done: Com o tipo de campo bool.

    E logo a seguir temos a função __str__ no qual será usada para representar um objeto model da classe Todo (tanto em representação de codigo, quanto no nosso site de admin. No qual iremos falar em seguida). Nesse caso a representação será o self.description beleza?

    Passo 10: Refletindo o model com o banco de dados usando migrações

    Agora que o model Todo ja foi criado, precisamos criar um arquivo de migração em nossa aplicaçao que irá relfetir nosso model. Refletindo no banco de dados de desenvolvimento criando atabela todo.

    Com isso, no seu terminal adicione o seguinte comando para que possamos criar o arquivo de migração:

    $ (venv) django_todo % python manage.py makemigrations
    Migrations for 'todo_app':
      todo_app/migrations/0001_initial.py
        - Create model Todo
    Python

    Se tudo der certo, um novo arquivo sera criado chamando 0001_initial.py dentro da pasta migrations do nosso aplicativo todo_app.

    Logo apos criar este arquivo de migrations é hora de refletir estas mudanças no banco de dados de desenvolvimento. Então, adicione o proximo comando a seguir para refletir esta tabela no banco de dados:

    $ (venv) django_todo % python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, contenttypes, sessions, todo_app
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0001_initial... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying auth.0010_alter_group_name_max_length... OK
      Applying auth.0011_update_proxy_permissions... OK
      Applying auth.0012_alter_user_first_name_max_length... OK
      Applying sessions.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying todo_app.0001_initial... OK # <-- nossapp aqui...
    
    Python

    Passo 11: Adicionando nosso model no site admin

    Ágora que criamos o modelo Todo na aplicação, criamos o arquivo de migração e logo em seguida refletimos no banco de dados, agóra é o momento de fazer com que nosso model Todo seja refletido também no site admin da nossa aplicação python/django.

    Vamos lá, abra no todo_app o arquivo admin.py e adicione o seguinte codigo:

    from django.contrib import admin
    from .models import Todo # <-- Importa o model todo.
    
    # Register your models here.
    admin.site.register(Todo) # <-- Registra o model todo no site admin.
    Python

    Salve o arquivo admin.py e já em seguida rode o proximo comando para criarmos um usuario superadmin para ter acesso ao site de administrador (que vem por padrão no django).

    (venv) django_todo % python manage.py createsuperuser
    Username (leave blank to use 'elias'): Admin
    Email address: 
    Password: 
    Password (again): 
    Superuser created successfully.
    Python

    Seguindo o código acima podemos ver o comando python manage.py createsuperuser que será usado para criar um usuario super admin que terá o mais alto nível no projeto que estamos criando (baseando-se nos padrões do Django).

    Lembrando que ao adicionar o password e o password (again) o seu password nao ira aparecer. Então, fique tranquilo se for a sua primeira vez criando um super usuario no django.

    Ágora com o projecto rodando, va para a seguinte url:

    http://127.0.0.1:8000/admin

    Se tudo estiver feito corretamente você verá a seguinte tela:

    Agora adicione o username e o password que você adicionou ao criar o super admin, e caso estejam corretos você será encaminhado para a seguinte tela:

    Se der uma olhada acima, poderá ver que a ação de adicionar o model Todo no site admin funcionou. Ágora você pode clicar no Todos, checar os to-dos que você criou e até adicionar alguns.

    Só para lembrar que os valores que estao aparecendo são o resultado da função __str__ que criamos la atraz. Então o resultado sendo listados acima seria o self.description 😉.

    O formulario acima será usado para criar um novo to-do quando você clicar em “ADD TODO +”.

    Eu te aconselho a não se preocupar com todos esses detalhes, apenas faça. Da para modificar várias coisas da tela de admin, mas quero focar nesses detalheas em uma postagem mais no futuro blz?

    Caso você queira aprender mais sobre edição da tela de admin do dajngo manda um comentario abaixo. Ficarei muito feliz em te responder.

    Passo 12: Listando os to-dos criados no site admin na template

    Agora que podemos criar novos to-dos pelo site de admin do django, podemos listar eles usando o sistema de template do django na template que a gente já construiu anteriormente.

    Neste caso, precisaremos modificar nossa view de TemplateView para ListView.

    A classe ListView recebe como parente a classe MultipleObjectTemplateResponseMixin que é um superset da classe TemplateView (usado anteriormente) porém com uma simples funcionalidade de aceitação de listagem de objetos. E a classe BaseListView que trata o queryset (a busca) dos objetos do model adicionado na view.

    Porém, antes de tudo precisamos criar uma view que irá:

    1. Receber o modelo que iremos buscar os dados.
    2. Apontar qual a template iremos renderizar o context.
    3. Como iremos ordenar os objetos do modelo Todo. Que neste caso e por ‘-id’, que em outras palavras será uma ordenação decrescente. No qual os todos criados recentemente serão os que iram ser mostrados primeiro.
    from django.views.generic import ListView
    from .models import Todo
    
    class TodoListView(ListView):
        model = Todo  # <-- Modelo que iremos usar para ser listado.
        template_name = 'todo_list.html'  # <--Qual a temlplate.
        context_object_name = 'todos'  # <-- Qual o context que sera usado na template.
        ordering = ['-id']  # <-- Como os valores serão ordenados.
    Python

    E também precisamos criar uma nova template no qual irá ficar com a maioria da lógica da template. Ágora, la no diretório todo_app/templates/ crie uma nova template chamada todo_list.html e adicione o seguinte codigo:

    {% extends "base.html" %}
    
    {% block content %}
    <div class="main-container">
        <form method="post" class="todo-form">
            <input type="text" class="input-form" placeholder="Add a new todo...">
            <button class="submit-button">Add Todobutton>
        form>
        <ul class="main-list-container">
            {% for todo in todos %}
                <li class="list {% if todo.is_done %} gray-background-two {% endif %}">
                    {{ todo.description }}
                    <div class="icons">
                        <a href="#">
                            {% if todo.is_done %}
                                <i class="far fa-check-square">i>
                            {% else %}
                                <i class="far fa-square">i>
                            {% endif %}
                        a>
                    div>
                li>
            {% empty %}
                <li class="list gray-background">🥺 Sem to-do por enquanto.li>
            {% endfor %}
        ul>
    div>
    
    <div class="pagination">
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-left">i>
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-left">i> 
            a>
    
            <span class="pagination-current">Page 1 of 3span>
    
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-right">i> 
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-right">i> 
            a>
        div>
    {% endblock content %}
    
    HTML

    Você pode ver na linha 10 do código acima que usando a linguagem de template do django, é possível criar um for loop com o context_object_name chamado ‘todos’ adicionado la no ultimo codigo da view TodoListView.

    Com isso, podemos iterar sobre todos os objetos to-dos criados la no site de admin. E até adicionar algumas lógicas caso necessário. Você pode observar-los da linha 10 a linha 25 toda á lógica que foi feita.

    Desta fórma, criamos uma nóva template no qual extende a template base.html. Precisamos remover o conteúdo da template base (pois o conteúdo foi transferido para esta nova template chamada todo_list.html). E adicionar as tags de onde ésta nova template ira ser carregada la no base.html.

    {% load static %}
    
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="{% static 'css/style.css' %}">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/fontawesome.min.css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/all.min.css">
        <title>My ToDotitle>
    head>
    <body>
        <div class="header-container">
            <h1>My Todoh1>
        div>
        {% block content %}
        {% endblock content %}
    body>
    html>
    HTML
    No código acima temos a nova versao da template base.html. Se objervar bem, esta bem vazia, pois removemos todo codigo principal para ser criada a nova template todo_list.html. 

    Porém, no lugar do código removido, novas tags foram incluidas chamadas {% block content %} e {% endblock content %}.

    Neste caso, como estamos extendendo a template base.html na template todo_list.html (ver primeira linha), o código da template todo_list.html será incluida dentro das tags da template base.html. Sendo assim gerando apenas um html que será renderizado pela view.

    Caso você queira aprender mais sobre a linguagem de template do django voce pode dar uma olhada nesta postagem no qual eu me aprofundo explicando como as templates se interagem no framework django.

    Passo 13: Criando formulario para adicionar novos to-dos.

    Agora que ja temos uma base do projeto ja feito precisamos fazer com que o formulario tenha uma funcionalidade de criar novos to-dos.

    E para isso precisamos criar um novo arquivo no nosso todo_app chamado forms.py no qual irá ser responsável de receber os dados e com a view envia-los para a tabela to-do.

    from django import forms
    from .models import Todo
    
    class TodoForm(forms.ModelForm):
        class Meta:
            model = Todo
            fields = ['description']
            widgets = {
                'description': forms.TextInput(attrs={
                    'class': 'input-form',
                    'placeholder': 'Add a new todo...'
                })
            }
    Python

    No código acima adicionamos um formulario ModelForm que usa como padrão os campos de um model. Não necessitando de adicionar os tipos de cada campo, mas sim listando apenasos necessarios para criação de um objeto. Com o ModelForm, nosso formulário irá usar a tipagem do proprio model Todo.

    Detalhando o formulario TodoForm criado acima temos os seguintes campos:

    1. Classe Meta: Usado para atribuir metadados requeridos para a classe ModelForm.
    2. Atributo model: Que espera um model válido e criado no seu arquivo models.py.
    3. Atributo fields: Que espera que você liste todos ou quase todos os campos do model especificado.
    4. Atributo widgets (opicional): Usado para você personalizar os campos do formulario.

    Ágora que voce tem um detalhe dos atributos do ModelForm, especificando para a nossa necessidade, este formulario recebe um model chamado Todo. No qual tem apenas o campo ‘descripition’, que será aceito o recebimento de dados internamente. E para o atributo widgets será passado os atributos de html que já estão no nosso html puro.

    Lembrando que o form do django ao ser renderizado na template se tornara em html. 😉

    Otimizando a TodoListView para receber o TodoForm e renderiza-lo no template

    Se você prestar atenção, o formulario desta nossa aplicação fica na mesma template todo_list.html com isso, acredito que não será necessário criar uma nova template apenas para o formulario.

    Sendo assim, iremos melhorar o nosso TodoListView para renderizar o formulario em nosso template existente com adição do formulario na mesma.

    Para isso, voce ira precisar importar o formulario que acabou de criar para dentro da view e seguir o código que irei adicionar abaixo:

    from django.views.generic import FormView, ListView
    from django.urls import reverse_lazy
    from .models import Todo
    from .forms import TodoForm
    
    class TodoListView(ListView, FormView):
        model = Todo
        template_name = 'todo_list.html'  
        context_object_name = 'todos' 
        form_class = TodoForm # <-- Adição do formulario pelo atributo form_class.
        success_url = reverse_lazy('todo-list') # <-- Redirecionamento ao submeter o formulário.
        ordering = ['-id']  
    
        def form_valid(self, form): # <-- Valida o formulario
            form.save()  
            return super().form_valid(form)
    
        def get_context_data(self, **kwargs): # <-- Traz a tona o context_data para cutomiza-lo.
            context = super().get_context_data(**kwargs)
            context['form'] = self.get_form()  # <-- Adiciona o 'form' para o context_data
            return context
    Python

    Nesta nova versão do TodoListView foram adicionados novos atributos como:

    1. Atributo form_class: Que recebe o formulario que acabamos de criar (no nosso caso o TodoForm).
    2. Atributo success_url: Que serve para apontar qual url iremos redirecionar o usuario ao submeter o formulario. Neste caso, iremos redirecionar para a mesma pagina/url. Pois como não estamos criando uma aplicação reativa, precisamos redirecionar para recarregar a pagina e chamar a view novamente.

    E também novas funcionalidades/métodos como:

    1. Metodo form_valid(): Que serve para validar o formulario com os campos que serão enviados no mesmo.
    2. Metodo get_context_data(): Que será usado para trazer a tona o context_data que vem de uma herança lá da classe MultipleObjectMixin do Django. Com isso, vocÊ poderá adicionar um valor a mais dentro do context como o ‘form’ e renderiza-lo na template. Da mesma forma que fizemos com o ‘todos’.

    Renderizando o formulario no nosso template todo_list.html

    Agora que tudo esta pronto, o formulário, a validação do formulario na view e a adição do mesmo no contexto, esta na hora de pega-lo do context e adicionar-mos na template, onde será renderizado.

    {% extends "base.html" %}
    
    {% block content %}
    <div class="main-container">
        <form method="post" class="todo-form">
            {% csrf_token %}
            {{ form.description }}
            <button class="submit-button">Add Todobutton>
        form>    <ul class="main-list-container">
            {% for todo in todos %}
                <li class="list {% if todo.is_done %} gray-background-two {% endif %}">
                    {{ todo.description }}
                    <div class="icons">
                        <a href="#">
                            {% if todo.is_done %}
                                <i class="far fa-check-square">i>
                            {% else %}
                                <i class="far fa-square">i>
                            {% endif %}
                        a>
                    div>
                li>
            {% empty %}
                <li class="list gray-background">🥺 Sem to-do por enquanto.li>
            {% endfor %}
        ul>
    div>
    
    <div class="pagination">
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-left">i>
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-left">i> 
            a>
    
            <span class="pagination-current">Page 1 of 3span>
    
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-right">i> 
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-right">i> 
            a>
        div>
    {% endblock content %}
    
    Python

    Como nosso formulario esta bem no topo do documento, você podera ver que foi adicionado uma tag {% csrf_token %} usado para evitar falsificação de solicitação entre sites. E logo abaixo podemos ver o form sendo usado como expressão para adicionar o campo description, {{ form.description }} na template.

    Agora que ele foi adicionado, vamos ver como que ele éw renderizado na aplicação no browser:

    Zoom do formulario renderizado:

    1. Como você pode ver o nosso formulario renderiza um elemento html como todos atributos necessários vindos do models, e também aqueles que adicionamos no widgets do TodoForm.
    2. Além do mais também podemos ver outra elemento como type=hidden no qual adiciona um token csrf. Como este nao é o escopo deste tutorial não sera detalhado neste momento.

    Desta maneira já podemos adicionar novos to-dos em nossa aplicação.

    Passo 14: Alternando estado dos to-dos para completo e vice-versa

    Sendo assim, ja podemos listar os afazeres (to-dos) precisamos mudar o status do mesmo para completo e vice-versa. Com isso, precisamos de certa forma criar uma funcionalidade no qual, ao clicar no icone de checkbox (na parte do cliente) ele mude o estado do objeto Todo.is_done = False para Todo.is_done = True ou o contrario. Fazendo com que onde o objeto esteja completo, mude a cor do container no frontend.

    No django template language temos a possiblidade de ao clicar em um botão, enviarmos uma requisição para uma url com dados necessários se for possível. E esta url estara sendo receptada por uma view que irá tratar os dados que foram enviadas pelo cliente (usuario) ao clicar no botao.

    La no for loop que adicionamos no template todo_list.html para listar os to-dos, será adicionado uma tag do DTL (django template language) para enviar uma ação para url e depois da url para a view:

    ⚠⚠⚠⚠ Apenas código de exemplo NÂO COPIE ⚠⚠⚠⚠
    -- RESTANTE DO CODIGO DA TEMPLATE ACIMA --
    <ul class="main-list-container">
            {% for todo in todos %}
                <li class="list {% if todo.is_done %} gray-background-two {% endif %}">
                    {{ todo.description }}
                    <div class="icons">
                        <a href="#"> <-- Nossa ação será inserida onde se encotrar este #...
                            {% if todo.is_done %}
                                <i class="far fa-check-square">i>
                            {% else %}
                                <i class="far fa-square">i>
                            {% endif %}
                        a>
                    div>
                li>
            {% empty %}
                <li class="list gray-background">🥺 Sem to-do por enquanto.li>
            {% endfor %}
        ul>
    -- RESTANTE DO CODIGO DA TEMPLATE ABAIXO --
    HTML

    Como você pode ver acima temos o for loop usado para listar os to-dos como elementos

  • de uma lista. E um elemento com atributo href que nos permite lincar para outras páginas (assim com você ja sabe provavelmente).

    Com este href teremos a habilidade de adicionar um tag de template (DTL – django template language) para enviar uma requisição em uma url especifica, de um to-do especifico pelo id do objeto em questão:

    Que será transformado, dinamicamente, em um link no qual irá chamar a view ToggleTodoView:

    Com esta nova tag de template você pode fazer o update do seu código de template para o seguinte:

    {% extends "base.html" %}
    
    {% block content %}
    <div class="main-container">
        <form method="post" class="todo-form">
            {% csrf_token %}
            {{ form.description }}
            <button class="submit-button">Add Todobutton>
        form>    <ul class="main-list-container">
            {% for todo in todos %}
                <li class="list {% if todo.is_done %} gray-background-two {% endif %}">
                    {{ todo.description }}
                    <div class="icons">
                        <a href="{% url 'toggle-todo' todo.id %}">
                            {% if todo.is_done %}
                                <i class="far fa-check-square">i>
                            {% else %}
                                <i class="far fa-square">i>
                            {% endif %}
                        a>
                    div>
                li>
            {% empty %}
                <li class="list gray-background">🥺 Sem to-do por enquanto.li>
            {% endfor %}
        ul>
    div>
    
    <div class="pagination">
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-left">i>
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-left">i> 
            a>
    
            <span class="pagination-current">Page 1 of 3span>
    
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-right">i> 
            a>
            <a href="#" class="pagination-link">
                <i class="fas fa-angle-double-right">i> 
            a>
        div>
    {% endblock content %}
    Python

    Agora que adicionamos a tag de url apontando para uma url especifica e também passando o id do objeto to-do, é hora de criar uma nova url para receptar esta ação e enviar para uma view que irá tratar esta ação de mudar o estatus de Todo.is_done.

    Com isso, no diretorio todo_app/urls.py adicione o seguinte codigo:

    from django.contrib import admin
    from django.urls import path
    from .views import (
      TodoListView, 
      ToggleTodoView, # <-- Novo código
    )
    
    urlpatterns = [
        path('', TodoListView.as_view(), name='todo-list'),
        path('toggle-todo//', ToggleTodoView.as_view(), name='toggle-todo'), # <-- Novo código
    ]
    Python

    Iremos importar a classe que ainda iremos criar chamado ToggleTodoView, e criaremos a url como acima. Perceba que:

    1. A url espera um parametro de um número inteiro como o id do to-do, que já esta sendo enviado pela tag que adicionamos no codigo da template acima.
    2. Passando a classe que irá receber a requisição nesta url.
    3. E por fim o nome da url que usamos para adicionar na nossa ação na template com nome de ‘toggle-todo’.

    Com a nossa url pronta, agora, apenas precisamos de criar a nossa view chamada ToggleTodoView.

    from django.shortcuts import redirect, get_object_or_404
    from django.views.generic import FormView, ListView, View
    from django.urls import reverse_lazy
    from .models import Todo
    from .forms import TodoForm
    
    
    class TodoListView(ListView, FormView):
        model = Todo
        template_name = 'todo_list.html'
        context_object_name = 'todos'  
        form_class = TodoForm
        success_url = reverse_lazy('todo-list')
        ordering = ['-id']  
    
        def form_valid(self, form):
            form.save()  
            return super().form_valid(form)
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['form'] = self.get_form()  
            return context
    
        
    class ToggleTodoView(View): # <-- Nossa nova view
        def get(self, request, todo_id):
            todo = get_object_or_404(Todo, id=todo_id) # <-- Buscando to-do no banco de dados.
            todo.is_done = not todo.is_done  # <-- Aqui e onde o objeto e modificado de status.
            todo.save()
            return redirect('todo-list')
    Python

    Por fim, a classe ToggleTodoView onde será feita a ação final, logo após você clicar no checkbox que representa esta view.

    1. Com isso, podemos ver que na função get(), ela espera a requisição (request) e o todo_id que está vindo da url.
    2. Estes parametros são passados para dentro da função, onde é usada a função django get_object_or_404() onde o todo_id é inserido em uma query na tabela de todos.
    3. Logo em seguida, o valor desta query é passada para a variável todo no qual será usada para transformar estado do todo em is_done=True ou vice-versa.
    4. Na proxima linha esta mudança é salva, e por fim é redirecionado para a url name ‘todo-list’. No qual “recarrega” a página, fazendo assim você ver a mudança de estado do objeto, no qual você acabou de acabar. Tudo isso em um segundo ou menos 😅.

    Na imagem abaixo você consegue entender melhor todo fluxograma em uma ordem diferente:

    Passo 15: Criando paginação em nossa aplicação python e django

    Neste ultimo passo iremos trabalhar desenvolvendo a paginação do projeto. Para quem não sabe o que é paginação, é simplesmente um método no qual dividimos a quantidade de objetos de uma query no número no qual desejamos serem divididos. E é desenvolvido uma funcionalidade para navegar entre esas fatias com os valores.

    O por que precisamos desenvolver um sistema de paginação? Para gerenciar a quantidade de items que iram aparecer na tela. Não deixando uma multidão do mesmo tomando conta da tela.

    Nesta imagem abaixo é o que ira acontecer caso você adicione to-dos sem uma paginação:

    Como pode ver, ficaria um número enorme de items que podem até quebrar a aplicação no frontend (pois não temos um freio da quantidade de items que podem aparecer na tela).

    Para isso, o django nos oferece a paginação para que podemos dividir estes items em números vistos por vez. No qual podemos navegar por vez usando alguns links na base destes items no frontend.

    Como a paginação funciona?

    Nós escolhemos qual o número de items iram aparecer por vez, e o sistema de paginação do django irá dividir esses items pelo número no qual você escolheu. Assim, ao clicar em um link de navegação poderemos ir para frente ou para traz nesses items.

    No exemplo abaixo, vamos supor que escolhemos que apenas 5 items apareça por vez, com 16 items to-do:

    Tendo 16 to-dos, teremos 4 paginas, onde, 3 teram 5 items cada, e uma com apenas 1 item to-do. Com isso, só precisamos criar uma funcionalidade no qual irá fazer este serviço pra gente, e adicionar a lógica na template.

    from django.shortcuts import redirect, get_object_or_404
    from django.views.generic import FormView, ListView, View
    from django.urls import reverse_lazy
    from .models import Todo
    from .forms import TodoForm
    
    
    class TodoListView(ListView, FormView):
        model = Todo
        template_name = 'todo_list.html'
        context_object_name = 'todos'  
        form_class = TodoForm
        success_url = reverse_lazy('todo-list')
        ordering = ['-id']  
        paginate_by = 5 # <-- Aqui adicionaremos o número de paginação.
    
        def form_valid(self, form):
            form.save()  
            return super().form_valid(form)
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['form'] = self.get_form()  
            return context
    
        
    class ToggleTodoView(View):
        def get(self, request, todo_id):
            todo = get_object_or_404(Todo, id=todo_id) 
            todo.is_done = not todo.is_done
            todo.save()
            return redirect('todo-list')
    Python

    No exemplo acima, apenas adicionamos uma linha na classe TodoListView chamada paginated_by no qual é herdada da seguinte maneira:

    TodoListView <-- ListView <-- BaseListView <-- MultipleObjectMixin

    O paginate_by = 5 indica que a página retornará no máximo 5 objetos por vez. O Django automaticamente adicionará suporte à paginação na sua view, criando um objeto paginator e inserindo a variável “page_obj“ no contexto do template, assim como “todos” e “form” que adicionamos previosmente.

    Agora com o “page_obj” no contexto da template, podemos adicionar a lógica de paginação na template:

    **** Apenas codigo de exemplo NÂO COPIE ****
    -- RESTANTE DO CODIGO DA TEMPLATE ACIMA --
    
    <div class="pagination">
        {% if page_obj.has_previous %}
            <a href="?page=1" class="pagination-link">
                <i class="fas fa-angle-double-left">i> 
            a>
            <a href="?page={{ page_obj.previous_page_number }}" class="pagination-link">
                <i class="fas fa-angle-left">i> 
            a>
        {% endif %}
    
        <span class="pagination-current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
        span>
    
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}" class="pagination-link">
                <i class="fas fa-angle-right">i> 
            a>
            <a href="?page={{ page_obj.paginator.num_pages }}" class="pagination-link">
                <i class="fas fa-angle-double-right">i> 
            a>
        {% endif %}
    div>
    {% endblock content %}
    HTML

    O que aconteceu no codigo acima?

    1. Exibindo os botões “Primeira Página” e “Anterior”

    {% if page_obj.has_previous %}
      <a href="?page=1" class="pagination-link">
          <i class="fas fa-angle-double-left">i> 
      a>
    
      <a href="?page={{ page_obj.previous_page_number }}" class="pagination-link">
          <i class="fas fa-angle-left">i> 
      a>
    {% endif %}
    HTML

    O Django nos dá a variável page_obj, que representa a página atual. Se houver uma página anterior (page_obj.has_previous), os botões de voltar são mostrados:

    Os ícones são do FontAwesome, mas você pode trocar por texto, se quiser!

    2. Mostrando a página atual

    Aqui, mostramos qual página o usuário está vendo e quantas existem no total:

    <span class="pagination-current">
        Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
    span>
    HTML

    Se você estiver na página 3 de 10, verá algo como:

    Page 3 of 10

    Só lembrar do exemplo que fizemos acima com as imagens.

    3. Exibindo os botões “Próxima Página” e “Última Página”

    Se houver mais páginas depois da atual (page_obj.has_next), os botões de avançar aparecem:

    {% if page_obj.has_next %}
      <a href="?page={{ page_obj.next_page_number }}" class="pagination-link">
          <i class="fas fa-angle-right">i> 
      a>
      
      <a href="?page={{ page_obj.paginator.num_pages }}" class="pagination-link">
          <i class="fas fa-angle-double-right">i> 
      a>
    {% endif %}
    HTML

    Agora que a paginação esta concluida, desta maneira que ira ficar a template todo_list.html.

    {% extends "base.html" %}
    
    {% block content %}
    <div class="main-container">
        <form method="post" class="todo-form">
            {% csrf_token %}
            {{ form.description }}
            <button class="submit-button">Add Todobutton>
        form>
        <ul class="main-list-container">
            {% for todo in todos %}
                <li class="list {% if todo.is_done %} gray-background-two {% endif %}">
                    {{ todo.description }}
                    <div class="icons">
                        <a href="{% url 'toggle-todo' todo.id %}">
                            {% if todo.is_done %}
                                <i class="far fa-check-square">i>
                            {% else %}
                                <i class="far fa-square">i>
                            {% endif %}
                        a>
                    div>
                li>
            {% empty %}
                <li class="list gray-background">🥺 Sem to-do por enquanto.li>
            {% endfor %}
        ul>
    div>
    
    <div class="pagination">
        {% if page_obj.has_previous %}
            <a href="?page=1" class="pagination-link">
                <i class="fas fa-angle-double-left">i> 
            a>
            <a href="?page={{ page_obj.previous_page_number }}" class="pagination-link">
                <i class="fas fa-angle-left">i> 
            a>
        {% endif %}
    
        <span class="pagination-current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
        span>
    
        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}" class="pagination-link">
                <i class="fas fa-angle-right">i> 
            a>
            <a href="?page={{ page_obj.paginator.num_pages }}" class="pagination-link">
                <i class="fas fa-angle-double-right">i> 
            a>
        {% endif %}
    div>
    {% endblock content %}
    HTML

    Conclusão

    Parabéns por chegar até aqui! O fato de você ter acompanhado todas as etapas desta postagem mostra que está realmente comprometido em aprender o Django, um dos frameworks mais poderosos do Python.

    Criar uma aplicação To-Do pode parecer simples à primeira vista, mas compreender como o básico do Django realmente funciona faz toda a diferença no seu dia a dia. Esse conhecimento sólido facilitará o desenvolvimento de novos projetos, seja para uso pessoal ou no seu trabalho.

    Foi exatamente por isso que fui a fundo neste tutorial: para ajudar pessoas como você a dominar o Django de forma clara e prática.

    Ao longo desta jornada, aprendemos a:

    • Iniciar um projeto Django e criar um app conectado a ele.
    • Configurar e utilizar arquivos estáticos.
    • Entender e aplicar o padrão MVT (Model-View-Template).
    • Criar models, views e templates de maneira estruturada.
    • Criamos formularios, usando o ModelForm do django.
    • Aproveitando o poder das class-based views (CBVs), herdando funcionalidades do Django para acelerar o desenvolvimento.

    Agora que você tem essa base bem construída, o próximo passo é praticar e aprofundar ainda mais seu conhecimento. Continue explorando, criando novos projetos e aprimorando suas habilidades. O Django é um universo cheio de possibilidades, e você está no caminho certo para dominá-lo!

    Se este tutorial te ajudou, compartilhe com outras pessoas que também querem aprender Django e deixe seu comentário abaixo. Vou adorar saber como foi sua experiência

  • Como integrar frameworks frontend como React com Django

    Como integrar frameworks frontend como React com Django

    Hoje em dia, é comum trabalhar com uma aplicação que separa o frontend do backend. E para isso, dois grandes nomes aparecem: Django no backend e React no frontend.

    Django é um framework poderoso que oferece uma robusta estrutura de backend, enquanto React é amplamente utilizado para construir interfaces dinâmicas e reativas no frontend.

    A pergunta é: como fazer esses dois mundos conversarem bem? Afinal, enquanto o Django se preocupa com bancos de dados, autenticação e regras de negócio, o React está mais interessado em manipular DOM e interações rápidas com o usuário.

    Neste artigo, vamos explorar o processo de integrar o React como frontend e o Django como backend. Vamos ver desde a configuração de um ambiente básico até a criação de uma API REST com Django e seu consumo por meio de uma aplicação React.

    Tudo isso com detalhes, exemplos de código e boas práticas que vão te ajudar a construir uma aplicação que tire o melhor dos dois frameworks.

    Arquiteturas de Integração: Monolito vs. Aplicações Separadas

    Quando pensamos em integrar React com Django, existem duas abordagens principais:

    1. Monolítica: O Django controla tudo, incluindo a entrega do frontend. Nesse caso, o React pode ser usado de forma mais limitada, talvez para melhorar a interatividade de alguns componentes específicos no frontend, mas sem ser uma SPA (Single Page Application) completa.
    2. Desacoplada (SPA): Aqui, o Django fica totalmente focado no backend, sendo responsável por fornecer uma API RESTful (usando Django REST Framework, por exemplo), enquanto o React lida exclusivamente com o frontend. Essa é a abordagem típica quando estamos falando de Single Page Applications (SPA).

    Qual escolher?

    A escolha entre essas duas arquiteturas depende do tipo de projeto que você está construindo:

    • Monolítica: Ótima para aplicações menores ou quando você deseja integrar interações mais simples, mantendo o poder dos templates Django.
    • Desacoplada (SPA): Ideal para aplicações mais complexas, onde o frontend precisa ser muito dinâmico e interativo. React pode cuidar das interações e renderizações do lado do cliente, enquanto Django gerencia as regras de negócio e a API.

    Como vamos tratar de uma integração mais completa, focaremos na segunda abordagem, criando uma aplicação desacoplada, onde o Django serve uma API REST e o React consome essa API para exibir dados no frontend.

    Configurando o Ambiente para Integração

    Agora que entendemos a arquitetura, vamos configurar o ambiente para integrar React e Django.

    Passo 1: Configurando o Django

    Primeiro, vamos criar um projeto Django. No terminal, execute o seguinte comando:

    django-admin startproject meu_projeto
    cd meu_projeto
    Bash

    Agora, vamos criar um app para lidar com nossa API, usando o Django REST Framework. Instale o Django REST Framework:

    pip install djangorestframework
    Bash

    Depois, no arquivo settings.py, adicione o rest_framework aos apps instalados:

    INSTALLED_APPS = [
        ...
        'rest_framework',
        'meu_app',  # Seu app para a API
    ]
    Python

    Agora, configure o Django REST Framework:

    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.AllowAny',
        ]
    }
    Python

    Passo 2: Configurando o React

    Vamos agora configurar o React. No diretório raiz do projeto (fora do diretório do Django), crie o projeto React:

    npx create-react-app frontend
    Bash

    Isso vai criar uma estrutura de projeto React. Esse diretório frontend será onde você irá desenvolver todo o frontend da aplicação, completamente separado do Django.

    Criando a API no Django

    Agora que temos o Django configurado, vamos construir uma API RESTful para servir os dados que o React vai consumir.

    Passo 1: Criando um Modelo Simples

    Vamos criar um modelo simples de Produto para exemplo. No arquivo models.py do seu app, adicione o seguinte:

    from django.db import models
    
    class Produto(models.Model):
        nome = models.CharField(max_length=100)
        preco = models.DecimalField(max_digits=10, decimal_places=2)
        descricao = models.TextField()
    
        def __str__(self):
            return self.nome
    Python

    Após isso, execute as migrações:

    python manage.py makemigrations
    python manage.py migrate
    Bash

    Passo 2: Criando a API com Django REST Framework

    Agora, vamos criar um serializer para nosso modelo. Crie um arquivo serializers.py e adicione:

    from rest_framework import serializers
    from .models import Produto
    
    class ProdutoSerializer(serializers.ModelSerializer):
        class Meta:
            model = Produto
            fields = '__all__'
    Python

    Depois disso, crie a view para a API no views.py:

    from rest_framework import viewsets
    from .models import Produto
    from .serializers import ProdutoSerializer
    
    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
    Python

    Por fim, adicione as rotas da API no urls.py do app:

    from django.urls import path, include
    from rest_framework.routers import DefaultRouter
    from .views import ProdutoViewSet
    
    router = DefaultRouter()
    router.register(r'produtos', ProdutoViewSet)
    
    urlpatterns = [
        path('api/', include(router.urls)),
    ]
    Python

    Passo 3: Configurando o django-cors-headers

    Quando integramos React e Django, especialmente em uma arquitetura desacoplada, onde o backend Django e o frontend React estão em servidores ou portas diferentes, precisamos habilitar o CORS (Cross-Origin Resource Sharing).

    Isso é necessário porque, por padrão, os navegadores bloqueiam requisições feitas de uma origem diferente daquela de onde o frontend foi carregado (uma medida de segurança chamada Same-Origin Policy).

    O que é CORS?

    CORS (Cross-Origin Resource Sharing) é um mecanismo que permite que uma aplicação frontend (por exemplo, React) faça requisições a um servidor backend (Django) que está em um domínio diferente.

    No nosso caso, o frontend React rodaria em uma origem como http://localhost:3000, enquanto o backend Django estaria em http://localhost:8000. Isso normalmente resultaria em um erro de CORS policy, bloqueando as requisições.

    Solução: Usando django-cors-headers

    Para permitir que o frontend React se comunique com o backend Django, precisamos instalar e configurar o pacote django-cors-headers. Ele adiciona os cabeçalhos necessários para que as requisições entre diferentes origens sejam permitidas.

    Passo 3.1: Instalando o django-cors-headers

    Primeiro, vamos instalar o pacote:

    pip install django-cors-headers
    Bash

    Passo 3.2: Configurando o django-cors-headers

    Agora, precisamos configurar o Django para usar o django-cors-headers. No arquivo settings.py, siga os seguintes passos:

    1. Adicione corsheaders na lista de INSTALLED_APPS:
    INSTALLED_APPS = [
        # Outros apps...
        'corsheaders', # <-- Aqui
        'rest_framework',
        'meu_app',
    ]
    Python
    1. Adicione o middleware do corsheaders antes do CommonMiddleware:
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        # Outros middlewares...
    ]
    Python
    1. Defina os domínios permitidos para fazer requisições à API Django. No caso do desenvolvimento, permitimos que o React rodando em localhost:3000 faça requisições:
    CORS_ALLOWED_ORIGINS = [
        "http://localhost:3000",
    ]
    Python

    Com essa configuração, permitimos que qualquer requisição vinda do React (no endereço http://localhost:3000) seja aceita pelo Django.

    Agora, sua API está pronta para ser consumida pelo React. Se você rodar o servidor Django (python manage.py runserver), pode acessar os produtos em http://localhost:8000/api/produtos/.

    Integração com React

    Agora que a API está pronta, vamos conectar o React a ela.

    Passo 1: Consumindo a API no React

    No projeto React, vamos usar o axios para fazer requisições à API Django. Primeiro, instale o axios:

    npm install axios
    Bash

    Agora, crie um componente para listar os produtos. No diretório src, crie um arquivo Produtos.js:

    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    
    const Produtos = () => {
      const [produtos, setProdutos] = useState([]);
    
      useEffect(() => {
        axios.get('http://localhost:8000/api/produtos/')
          .then(res => {
            setProdutos(res.data);
          })
          .catch(err => {
            console.log(err);
          });
      }, []);
    
      return (
        <div>
          <h1>Lista de Produtosh1>
          <ul>
            {produtos.map(produto => (
              <li key={produto.id}>{produto.nome} - R${produto.preco}li>
            ))}
          ul>
        div>
      );
    };
    
    export default Produtos;
    JavaScript

    Esse componente faz uma requisição à API Django e exibe a lista de produtos. Agora, basta adicionar o componente Produtos ao App.js do React:

    import React from 'react';
    import Produtos from './Produtos';
    
    function App() {
      return (
        <div className="App">
          <Produtos />
        div>
      );
    }
    
    export default App;
    JavaScript

    Rodando o projeto React (npm start), você verá a lista de produtos sendo exibida, consumida diretamente da API Django.

    Autenticação e Autorização

    Agora que a API está funcionando, você pode querer proteger certos endpoints. Vamos implementar autenticação com JWT (JSON Web Token).

    Passo 1: Instalando o Django REST Framework JWT

    Instale a biblioteca de autenticação JWT:

    pip install djangorestframework-simplejwt
    Bash

    Adicione as configurações no settings.py:

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ],
    }
    Python

    Adicione as rotas de autenticação JWT no urls.py do projeto:

    from rest_framework_simplejwt.views import (
        TokenObtainPairView,
        TokenRefreshView,
    )
    
    urlpatterns = [
        path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
        path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ]
    Python

    Agora, você pode fazer login via POST na rota /api/token/ e obter o token JWT. Esse token deve ser enviado nas requisições seguintes, no header Authorization: Bearer .

    Passo 2: Consumindo APIs Autenticadas no React

    No React, modifique o código de requisição para enviar o token JWT:

    axios.get('http://localhost:8000/api/produtos/', {
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      }
    })
    .then(res => setProdutos(res.data))
    .catch(err => console.log(err));
    JavaScript

    Servindo o React com Django (caso você queira)

    Quando for para produção, você pode servir o build do React diretamente no Django. Para isso, rode o comando npm run build no diretório React, que criará uma pasta build.

    No Django, crie uma view simples para servir o React:

    from django.shortcuts import render
    
    def index(request):
        return render(request, 'index.html')
    Python

    No urls.py do projeto Django, adicione:

    from django.urls import path
    from .views import index
    
    urlpatterns = [
        path('', index),
    ]
    Python

    Coloque os arquivos de build do React dentro de uma pasta templates no Django. Isso permitirá que o Django sirva o frontend React em produção.

    Melhores Práticas para Integração Django + React

    Algumas boas práticas incluem:

    1. Mantenha o frontend e o backend bem separados: Evite misturar lógica de backend no frontend e vice-versa. Isso facilita a manutenção e evolução do projeto.
    2. Use ferramentas de build automatizado: Ferramentas como Webpack podem ajudar a automatizar o processo de build e minificação do React.
    3. Autenticação segura: Sempre valide os tokens JWT e use HTTPS em produção para garantir a segurança da aplicação.
    4. Versionamento da API: Quando sua aplicação crescer, versionar a API garantirá que as mudanças não quebrem o frontend.

    Conclusão

    Integrar React com Django permite que você tire proveito do poder de cada framework. O Django lida com o backend e a lógica de negócios, enquanto o React garante uma interface de usuário rápida e responsiva.

    Ao seguir as práticas mostradas aqui, você pode criar uma aplicação escalável e bem organizada, que aproveita o melhor dos dois mundos.

    Ao final, React e Django, quando bem integrados, funcionam em harmonia, oferecendo uma experiência robusta tanto para o desenvolvedor quanto para o usuário final. Afinal, a verdadeira mágica acontece quando frontend e backend trabalham juntos para entregar uma aplicação completa.

  • Django Rest Framework: Construindo APIs RESTful com Django.

    Django Rest Framework: Construindo APIs RESTful com Django.

    No desenvolvimento moderno de aplicações web, onde a separação entre front-end e back-end é essencial, o Django Rest Framework (DRF) se destaca como uma das principais ferramentas para criar APIs RESTful de forma rápida, segura e escalável.

    Uma API (Application Programming Interface) permite a comunicação entre sistemas diferentes, e o padrão REST (Representational State Transfer) tornou-se o mais utilizado por sua simplicidade e eficiência.

    O Django Rest Framework combina o poder do framework django com recursos avançados como autenticação, serialização e controle de permissões, tornando o desenvolvimento de APIs mais produtivo e padronizado.

    Por que REST é tão popular? Simples. Ele permite que sistemas possam se comunicar de forma eficiente e escalável, utilizando operações HTTP como GET, POST, PUT e DELETE para manipular recursos. Mas, como sempre, a teoria é uma coisa; na prática, pode ser bem mais desafiador. É aí que entra o Django REST Framework (DRF).

    O Django REST Framework é uma biblioteca poderosa que facilita a criação de APIs RESTful com Django. Ele oferece uma série de ferramentas que resolvem os problemas comuns na criação de APIs, como serialização de dados, controle de permissões, autenticação, tratamento de erros, e muito mais. E, como a maioria das bibliotecas Django, o DRF é altamente modular e extensível, o que permite que você customize quase todos os aspectos da sua API.

    Vamos direto ao ponto: nesta postagem, veremos como construir APIs RESTful utilizando o Django REST Framework, cobrindo desde a instalação e configuração básica até práticas avançadas como autenticação, filtragem, paginação, otimização e segurança…

    Instalação e Configuração do Django REST Framework

    Django Rest Framework

    Antes de qualquer coisa, você precisa ter um projeto Django em funcionamento. Se você ainda não tem um, basta criar um com os comandos:

    django-admin startproject minhaapi .
    Bash

    Agora, instale o Django REST Framework:

    pip install djangorestframework
    Bash

    Em seguida, adicione o rest_framework à lista de INSTALLED_APPS no arquivo settings.py:

    INSTALLED_APPS = [
        # Outros apps do Django...
        'rest_framework',
    ]
    Python

    Isso habilita o Django REST Framework no seu projeto.

    Configurações Iniciais

    No mesmo arquivo settings.py, podemos adicionar uma configuração básica para o DRF. Ela vai definir o comportamento padrão de permissões, autenticação e paginação da nossa API. Veja um exemplo simples:

    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.AllowAny',  # <- Permite acesso a qualquer usuário
        ],
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework.authentication.SessionAuthentication',  # <- Autenticação baseada em sessão
            'rest_framework.authentication.TokenAuthentication',    # <- Autenticação por token
        ],
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 10  # Número padrão de itens por página
    }
    Python

    Essa configuração é um ponto de partida. Definimos que a API permite qualquer requisição por enquanto (AllowAny), que ela pode usar autenticação por sessão ou por token, e que a paginação retorna 10 itens por página.

    Agora que já temos o Django REST Framework instalado e configurado, vamos criar nossa primeira API!

    Serializers: Convertendo Dados para APIs No Django Rest Framework

    Os serializers no Django REST Framework são responsáveis por converter instâncias de modelos do Django (ou outros tipos de dados complexos) em formatos simples que podem ser facilmente renderizados em JSON, ou outros formatos adequados para uma API.

    Há boatos que é possivel renderizar xml com django-rest-framework mas eu nunca vi como. Se você sabe como, ou já ouviu falar deixe um comentario aqui nesta postagem .Eu gostaria muito de saber como isso funciona.

    Imagine que temos um modelo de produto em nosso sistema Django:

    from django.db import models
    
    class Produto(models.Model):
        nome = models.CharField(max_length=100)
        descricao = models.TextField()
        preco = models.DecimalField(max_digits=10, decimal_places=2)
        data_criacao = models.DateTimeField(auto_now_add=True)
    
        def __str__(self):
            return self.nome
    Python

    Para expor esses dados via API, precisamos de um serializer que vai converter esse modelo para JSON e vice-versa. Veja como criar um serializer básico:

    from rest_framework import serializers
    from .models import Produto
    
    class ProdutoSerializer(serializers.ModelSerializer):
        class Meta:
            model = Produto
            fields = ['id', 'nome', 'descricao', 'preco', 'data_criacao']
    Python

    O ProdutoSerializer usa o ModelSerializer, que automaticamente mapeia os campos do modelo Produto. Isso nos poupa de definir manualmente cada campo no serializer, mas você pode fazer isso se precisar de mais controle sobre o que vai ser serializado.

    Um serializer mais manual ficaria assim:

    class ProdutoSerializer(serializers.Serializer):
        id = serializers.IntegerField(read_only=True)
        nome = serializers.CharField(max_length=100)
        descricao = serializers.CharField()
        preco = serializers.DecimalField(max_digits=10, decimal_places=2)
        data_criacao = serializers.DateTimeField()
    Python

    Este exemplo dá mais controle sobre o comportamento dos campos individuais, mas na maioria dos casos, o ModelSerializer é suficiente.

    Validação de Dados

    Uma das grandes vantagens dos serializers é que eles não apenas convertem dados, mas também validam automaticamente as entradas dos usuários. O ProdutoSerializer validará o tipo de dado, comprimento dos campos, entre outras coisas.

    Se você quiser adicionar validações personalizadas, pode sobrescrever o método validate() no serializer:

    class ProdutoSerializer(serializers.ModelSerializer):
        class Meta:
            model = Produto
            fields = '__all__'
    
        def validate_preco(self, value):
            if value <= 0:
                raise serializers.ValidationError("O preço deve ser maior que zero.")
            return value
    Python

    Neste exemplo, garantimos que o preço do produto não pode ser negativo. O Django REST Framework trata a validação automaticamente e retorna mensagens de erro apropriadas.

    Viewsets: Controlando as Requisições da API No Django Rest Framework

    Os Viewsets no Django REST Framework são uma forma poderosa de lidar com as requisições da API de forma eficiente. Eles combinam as funcionalidades de várias Views tradicionais do Django em uma única classe, permitindo um código mais conciso e fácil de manter.

    Uma Viewset simplifica bastante as coisas. Ela agrupa as ações de listagem, detalhamento, criação, atualização e deleção em uma única classe.

    Aqui está um exemplo de um Viewset para nosso modelo Produto:

    from rest_framework import viewsets
    from .models import Produto
    from .serializers import ProdutoSerializer
    
    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
    Python

    Com isso, o DRF automaticamente cria as rotas e métodos HTTP necessários para listar produtos, criar novos, atualizar e deletar, tudo em uma única classe. Isso economiza muito código repetitivo.

    O ModelViewSet inclui as seguintes ações por padrão:

    • list(): Retorna uma lista de objetos.
    • retrieve(): Retorna um objeto específico.
    • create(): Cria um novo objeto.
    • update(): Atualiza um objeto existente.
    • destroy(): Remove um objeto.

    Se quiser personalizar essas ações, você pode sobrescrevê-las. Por exemplo, se você quiser modificar o comportamento de listagem:

    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
    
        def list(self, request):
            queryset = Produto.objects.filter(preco__gte=10)  # Exemplo: apenas produtos com preço acima de 10 dinheiros
            serializer = ProdutoSerializer(queryset, many=True)
            return Response(serializer.data)
    Python

    Isso permite adicionar lógicas específicas para cada operação.

    Routers: Mapeando URLs para as Viewsets

    Para expor nossas Viewsets via URLs, o Django REST Framework oferece o conceito de routers, que simplificam o processo de mapeamento das URLs da API.

    Aqui está como podemos adicionar um router para nossa API de produtos:

    from rest_framework.routers import DefaultRouter
    from .views import ProdutoViewSet
    
    router = DefaultRouter()
    router.register(r'produtos', ProdutoViewSet)
    
    urlpatterns = [
        path('', include(router.urls)),
    ]
    Python

    O DefaultRouter gera automaticamente todas as rotas necessárias para as operações CRUD. Ele vai criar URLs como:

    • /produtos/: Para listar e criar produtos.
    • /produtos/{id}/: Para recuperar, atualizar ou deletar um produto específico.

    Isso elimina a necessidade de mapear manualmente cada URL, tornando o código mais limpo e fácil de manter.

    Se precisar de rotas personalizadas, como uma rota para buscar produtos por nome, você pode fazer isso criando uma Action:

    from rest_framework.decorators import action
    from rest_framework.response import Response
    
    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
    
        @action(detail=False, methods=['get'], url_path='buscar')
        def buscar_produto(self, request):
            nome = request.query_params.get('nome')
            produtos = Produto.objects.filter(nome__icontains=nome)
            serializer = self.get_serializer(produtos, many=True)
            return Response(serializer.data)
    Python

    Isso cria uma nova rota /produtos/buscar/?nome=play5-barato, que retorna produtos com o nome que contém o parâmetro passado.

    Permissões e Autenticação

    Uma API aberta para o público geral pode ser perigosa, especialmente quando estamos lidando com dados sensíveis. Por isso, garantir que apenas usuários autorizados possam acessar ou modificar recursos é essencial. O Django REST Framework torna esse processo muito fácil com seu sistema de permissões e autenticação.

    Permissões no Django REST Framework

    As permissões definem quem pode acessar certas views ou realizar certas ações. O Django REST Framework já traz algumas permissões básicas, que podem ser configuradas diretamente nas views ou viewsets.

    • AllowAny: Permite que qualquer pessoa acesse a view (inclusive usuários anônimos).
    • IsAuthenticated: Apenas usuários autenticados podem acessar.
    • IsAdminUser: Apenas administradores podem acessar.
    • IsAuthenticatedOrReadOnly: Usuários autenticados podem fazer tudo; usuários anônimos só podem ler.

    Podemos aplicar essas permissões diretamente nas viewsets:

    from rest_framework.permissions import IsAuthenticated
    
    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
        permission_classes = [IsAuthenticated]
    Python

    Aqui, apenas usuários logados poderão acessar as rotas da API de produtos.

    Autenticação com Tokens

    A autenticação baseada em tokens é uma das formas mais comuns de proteger APIs RESTful. O DRF oferece suporte nativo para autenticação com tokens, permitindo que os usuários façam login e recebam um token único, que será enviado com cada requisição subsequente para provar sua identidade.

    Para habilitar a autenticação por token, instale o pacote djangorestframework-simplejwt:

    pip install djangorestframework-simplejwt
    Bash

    Adicione as classes de autenticação ao settings.py:

    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ],
    }
    Python

    Agora, configure as rotas para obter e atualizar tokens no seu urls.py:

    from rest_framework_simplejwt.views import (
        TokenObtainPairView,
        TokenRefreshView,
    )
    
    urlpatterns = [
        path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
        path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ]
    Python

    Com isso, os usuários poderão obter um token de autenticação enviando suas credenciais (usuário e senha) para /api/token/. O token será então usado em cada requisição subsequente:

    curl -X POST http://localhost:8000/api/token/ -d "username=admin&password=12345"
    Python

    Isso retornará um token JWT, que deve ser enviado no cabeçalho Authorization em cada requisição subsequente:

    curl -H "Authorization: Bearer " http://localhost:8000/produtos/
    Python

    Filtragem, Ordenação e Paginação No Django Rest Framework

    APIs sem a capacidade de filtrar, ordenar e paginá-las podem se tornar um pesadelo de performance à medida que os dados crescem. O Django REST Framework oferece suporte nativo para esses recursos.

    Filtragem

    A filtragem permite que os clientes da API restrinjam os resultados com base em critérios específicos. Podemos usar o pacote django-filter para facilitar essa tarefa:

    pip install django-filter
    Bash

    Em settings.py, adicione a configuração para habilitar o django-filter no DRF:

    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
    }
    Python

    Agora, no views.py, podemos adicionar filtragem a nossa Viewset de produtos:

    from django_filters.rest_framework import DjangoFilterBackend
    
    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
        filter_backends = [DjangoFilterBackend]
        filterset_fields = ['nome', 'preco']
    Python

    Com isso, podemos filtrar produtos por nome e preco diretamente na URL:

    http://localhost:8000/produtos/?nome=Mouse&preco=50
    Python

    Ordenação

    Além de filtrar, podemos ordenar os resultados da API. Para isso, usamos a classe OrderingFilter:

    from rest_framework.filters import OrderingFilter
    
    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.all()
        serializer_class = ProdutoSerializer
        filter_backends = [DjangoFilterBackend, OrderingFilter]
        filterset_fields = ['nome', 'preco']
        ordering_fields = ['preco', 'data_criacao']
    Python

    Agora, podemos ordenar os produtos por preco ou data_criacao:

    http://localhost:8000/produtos/?ordering=preco
    http://localhost:8000/produtos/?ordering=-preco
    Python

    Paginação

    Paginar os resultados é crucial para APIs que podem retornar grandes volumes de dados. No Django REST Framework, a paginação pode ser configurada globalmente no settings.py ou individualmente em cada Viewset.

    Aqui está a configuração global para usar paginação baseada em números de página:

    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 10
    }
    Python

    Com essa configuração, a resposta da API será automaticamente paginada em blocos de 10 itens por vez. Para navegar pelas páginas, basta adicionar o parâmetro page à URL:

    http://localhost:8000/produtos/?page=2
    Python

    Testando APIs RESTful

    Uma das melhores práticas no desenvolvimento de software é testar suas APIs. Testes garantem que seu código funcione conforme esperado e que futuras alterações não quebrem nada.

    O Django REST Framework oferece o APIClient, uma ferramenta que facilita a escrita de testes para APIs. Vamos ver como testar nossa API de produtos.

    from rest_framework.test import APITestCase
    from django.urls import reverse
    from rest_framework import status
    from .models import Produto
    
    class ProdutoAPITest(APITestCase):
        
        def setUp(self):
            self.produto = Produto.objects.create(
                nome="Teclado",
                descricao="Teclado mecânico",
                preco=150.00
            )
        
        def test_listar_produtos(self):
            url = reverse('produto-list')
            response = self.client.get(url)
            self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        def test_criar_produto(self):
            url = reverse('produto-list')
            data = {'nome': 'Mouse', 'descricao': 'Mouse óptico', 'preco': 50.00}
            response = self.client.post(url, data, format='json')
            self.assertEqual(response.status_code, status.HTTP_201_CREATED)
    Python

    No teste acima, usamos o APITestCase para testar duas coisas: listar os produtos e criar um novo produto. Isso garante que nossas operações básicas da API estão funcionando como esperado.

    https://wordpress.vps9144.panel.icontainer.cloud/testes-unitarios-com-django/
    Só Para lembrar: Caso precise se aprofundar mais nos testes
    unitarios da um pulo na postagem acima ;D

    Melhorando Performance com Viewsets Otimizados

    Performance é sempre uma preocupação, especialmente quando se trata de APIs que podem ser acessadas por múltiplos clientes simultaneamente. O Django REST Framework permite otimizar as consultas ao banco de dados usando os métodos select_related() e prefetch_related().

    Esses métodos são úteis quando estamos lidando com relações entre modelos, como ForeignKey e ManyToManyField.

    Imagine que cada produto tenha um categoria, que é uma ForeignKey. Para evitar múltiplas consultas ao banco, podemos usar select_related:

    class ProdutoViewSet(viewsets.ModelViewSet):
        queryset = Produto.objects.select_related('categoria').all()
        serializer_class = ProdutoSerializer
    Python

    O select_related() carrega a relação ForeignKey em uma única consulta, reduzindo a sobrecarga no banco de dados.

    Evitando o Problema N+1 no Django Rest Framework

    Um dos problemas mais comuns em APIs mal otimizadas é o N+1 problem. Isso acontece quando a aplicação faz uma consulta principal (a primeira) e depois faz N outras consultas para obter dados relacionados, o que é extremamente ineficiente.

    Por exemplo, se tivermos uma lista de produtos, e cada produto tiver uma relação com uma categoria, sem select_related(), o Django faria uma consulta para listar os produtos e, depois, N consultas para cada uma das categorias associadas. O uso de select_related() evita isso.

    Tratamento de Erros e Exceções

    Ninguém gosta de ver erros sem sentido ao usar uma API. O Django REST Framework facilita o tratamento de exceções e erros para garantir que as respostas da API sejam claras e informativas.

    Por padrão, o DRF já lida com muitos erros comuns (como 404 Not Found ou 400 Bad Request). No entanto, você pode personalizar o comportamento criando suas próprias handlers de erro.

    Aqui está um exemplo de como capturar exceções e retornar uma resposta customizada:

    from rest_framework.views import exception_handler
    
    def custom_exception_handler(exc, context):
        response = exception_handler(exc, context)
        
        if response is not None:
            response.data['status_code'] = response.status_code
        
        return response
    Python

    Em settings.py, adicione a referência para esse handler:

    REST_FRAMEWORK = {
        'EXCEPTION_HANDLER': 'meuprojeto.utils.custom_exception_handler', 
    }
    Python

    Agora, todas as exceções serão tratadas pelo seu handler customizado, onde você pode adicionar informações extras à resposta, como status code, mensagens mais amigáveis, etc.

    Implementando Versionamento de API No Django Rest Framework

    Versionar uma API é crucial quando há a necessidade de fazer atualizações sem quebrar a compatibilidade com clientes antigos. O Django REST Framework facilita a implementação de versionamento, permitindo que você diferencie as versões da API nas URLs ou nos cabeçalhos.

    Versionamento nas URLs

    A abordagem mais comum é incluir a versão na URL. Aqui está um exemplo de como fazer isso:

    from rest_framework.versioning import URLPathVersioning
    
    REST_FRAMEWORK = {
        'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
    }
    
    urlpatterns = [
        path('api/v1/produtos/', ProdutoViewSet.as_view(), name='produtos-v1'),
        path('api/v2/produtos/', ProdutoViewSetV2.as_view(), name='produtos-v2'),
    ]
    Python

    Agora você tem duas versões da API rodando ao mesmo tempo. A versão v2 pode conter mudanças significativas sem afetar os clientes que ainda estão usando a v1.

    Documentação Automática com Swagger

    Uma boa documentação é essencial para qualquer API. O Django REST Framework pode gerar automaticamente uma documentação interativa para sua API usando ferramentas como o drf-yasg ou o Swagger.

    Instale o pacote:

    pip install drf-yasg
    Python

    Em seguida, adicione a configuração em urls.py:

    from rest_framework import permissions
    from drf_yasg.views import get_schema_view
    from drf_yasg import openapi
    
    schema_view = get_schema_view(
        openapi.Info(
            title="Minha API",
            default_version='v1',
            description="Documentação da API",
        ),
        public=True,
        permission_classes=(permissions.AllowAny,),
    )
    
    urlpatterns = [
        path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    ]
    Python

    Agora você pode acessar a documentação completa da sua API em /swagger/. A interface gerada pelo Swagger permite que os desenvolvedores vejam todas as rotas disponíveis, além de testar as requisições diretamente na página.

    Conclusão

    Neste artigo, detalhamos como construir APIs RESTful usando o Django REST Framework, passando desde a instalação e configuração até conceitos mais avançados, como autenticação por token, filtragem, paginação e otimização de consultas.

    Construir APIs pode parecer desafiador no início, mas o Django REST Framework oferece ferramentas maravilhosas para facilitar o desenvolvimento, mantendo um alto nível de flexibilidade e extensibilidade. Além disso, com boas práticas de segurança e documentação, a API que você criar estará pronta para ser consumida de forma eficiente e segura.

    Seguir as dicas e exemplos mostrados aqui, você terá uma API RESTful pronta para escalar.

    Se você chegou até aqui, parabéns! Agora é hora de colocar a mão na massa e construir suas próprias APIs.

  • Como Criar Um Pacote Django Privado

    Como Criar Um Pacote Django Privado

    Neste material, detalharei como você pode criar seu próprio pacote Django privado para ser reutilizado entre diferentes projetos.

    Portanto, para acompanhar, usaremos um aplicativo chamado cart que tem a função de manipular pedidos personalizados enviando-os para checkout. Este aplicativo será transformado em um pacote para ser usado por outros projetos Django, onde todos os passos serão explicados para você.

    Diretorio Inicial

    seu_pacote_django/
        └───cart/
            │   admin.py
            │   apps.py
            │   contexts.py
            │   models.py
            │   urls.py
            │   views.py
            │   __init__.py
            │   
            ├───migrations/
            │       __init__.py
            │       
            ├───templates/
            │       cart.html
            │       header2.html
            │
            └───tests/
                    test_urls.py
                    test_views.py
                    __init__.py
    Bash

    Como você pode ver, o diretório inicial tem apenas o aplicativo do carrinho dentro dele. Portanto, para iniciar seu pacote, você precisará criar mais arquivos que lidarão com o processo de construção do pacote, bem como alguns requisitos que você precisará caso, algum dia, queira torná-lo público, talvez adicionando-o ao PYPI.org.

    Arquivos Importantes Para Construir o Pacote Django:

    Nesta seção serão detalhados os arquivos necessários para construir o pacote do carrinho. Portanto, para facilitar o acompanhamento, a instrução será seguida como nome do arquivo + instrução + código.

    1. Arquivo Setup.py

    Este é o arquivo mais importante. setup.py representa main quando você chama as funções de instalação. Basicamente, dentro do setup.py você deve adicionar todas as informações necessárias para criar seu pacote. Como o nome do pacote, versão, licença e etc:

    # setup.py
    
    import os
    from setuptools import find_packages, setup
    
    with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
        README = readme.read()
    
    # allow setup.py to be run from any path
    os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
    
    setup(
        name='cart',
        version='0.0.1',
        packages=find_packages(),
        include_package_data=True,
        license='Your license', 
        description='A cart package that handles payments with stripe.',
        long_description=README,
        url='yoursite.com',
        author='you',
        author_email='your@email.com',
        classifiers=[
            'Environment :: Web Environment',
            'Framework :: Django',
            'Framework :: Django :: 3.2',  
            'Intended Audience :: For my own or company usage',
            'License :: OSI Approved :: Your License',  
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            'Programming Language :: Python :: 3',
            'Programming Language :: Python :: 3.6',
            'Programming Language :: Python :: 3.8',
            'Programming Language :: Python :: 3.9',
            'Topic :: Internet :: WWW/HTTP',
            'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
        ],
    )
    Python

    Existem outras maneiras de configurar o arquivo setup.py com abordagens diferentes. No entanto, eu sugeriria que esta é a melhor e mais fácil maneira de criar seu arquivo setup.py.

    2. README.rst file

    De acordo com fileinfo.com, a extensão .rst ou linguagem de marcação reStructuredText é um arquivo de texto que contém e suporta código escrito e estilizado. No site Sphinx, é detalhado que a extensão .rst é a principal linguagem de marcação para a criação e design de documentação de código. No entanto, este não é um arquivo realmente necessário para criar seu pacote privado, mas é essencial se um dia você quiser torná-lo público no pypi.org.

    clique em view raw para ver o formato de marcação.

    Your Django Package
    To install:
    
    pip install git+https://github.com/your_name/your_cart_package.git
    In your_project.settings.py add:
    
    INSTALLED_APPS = [
        ...
        'cart',
        ...
    ]
    Migrate the changes from the underwriting_manual app:
    
    $ python manage.py makemigrations cart
    
    $ python manage.py migrate cart
    In your_project.urls.py add:
    
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/', include('core.urls')),
        path('cart/', include('cart.urls')), # <=====
    ]
    RST

    3. Arquivo LICENSE.

    De acordo com a esri, um arquivo de licença é um arquivo de texto simples que fornece automaticamente as informações necessárias — como nome do produto, número de autorização e informações de contato do usuário — Software Authorization Wizard.

    Dependendo do nível de informação que você tem em seu aplicativo, eu aconselho você a ter um arquivo LICENSE bem adaptado para evitar qualquer problema no futuro. No entanto, o arquivo LICENSE também é essencial ao carregar seu pacote para pypi.org.

    /* Copyright (C) Your Company Systems, Inc - All Rights Reserved
     * Unauthorized copying of this file, via any medium is strictly prohibited
     * Proprietary and confidential
     * Written by your company attorney <you@yourcompany.com>, December 2021
     */
    Markdown

    Neste exemplo, usarei um modelo personalizado que pode ser editado por você:

    PS: Não sou advogado, portanto, o exemplo de licença não pode ser usado como um conselho ou exemplo do mundo real.

    4. MANIFEST.in file

    MANIFEST.in é um arquivo de texto que contém uma série de “comandos” em um formato definido pelo Distutils. Os comandos manifest permitem que você inclua ou exclua arquivos e diretórios específicos. Principalmente aqueles que não são reconhecidos pelo python como um diretório porque não contêm o init.py, como o diretório templates/ no Django. E arquivos que não têm a extensão .py e os arquivos que são usados ​​para construir o pacote, como LICENSE e README.rst.

    No entanto, o MANIFEST.in é basicamente um conjunto de comandos para incluir no pacote que será reconhecido pelo sdist ao construir seu pacote. Portanto, quando o pacote for criado, se um diretório ou arquivo for especificado, eles estarão lá quando o pacote for construído 😉.

    include LICENSE
    include README.rst
    recursive-include cart/templates *
    recursive-include cart/tests *
    INI

    Buildando o Pacote Django

    No momento em que você está seguindo este tutorial, no qual iniciamos apenas com o aplicativo cart , ele mudou. Portanto, se você fez tudo corretamente, seu diretório de trabalho deve ficar assim:

    seu_pacote_django/
      │   LICENSE
      │   MANIFEST.in
      │   README.rst
      │   setup.py
      │
      └───cart/
          │   admin.py
          │   apps.py
          │   contexts.py
          │   models.py
          │   urls.py
          │   views.py
          │   __init__.py
          │
          ├───migrations/
          │       __init__.py
          │
          ├───templates/
          │       cart.html
          │       header2.html
          │
          └───tests/
                  test_urls.py
                  test_views.py
                  __init__.py
    Bash

    Agora, há alguns passos que precisam ser seguidos para iniciar o processo de construção do seu pacote:

    Instale os pacotes sdist (distribuição de origem) e whell:

    pip install sdist && pip install wheel
    Bash

    nota: Eu consideraria criar um ambiente virtual e instalar os pacotes sdist e whell nele (não se esqueça de adicionar um arquivo .gitignore).

    Build do pacote Em Ação:

    No diretório raiz do pacote, adicione os seguintes comandos para finalmente compilar o pacote:

    python setup.py sdist && python setup.py bdist_wheel
    Bash

    Dessa forma o pacote será finalmente construído deixando você com o seguinte diretório:

    seu_pacote_django/
    │   .gitignore
    │   LICENSE
    │   MANIFEST.in
    │   README.rst
    │   setup.py
    │
    ├───build/
    │   ├───bdist.win-amd64
    │   └───lib
    │       └───cart/
    │           │   admin.py
    │           │   apps.py
    │           │   contexts.py
    │           │   models.py
    │           │   urls.py
    │           │   views.py
    │           │   __init__.py
    │           │
    │           ├───migrations/
    │           │       __init__.py
    │           │
    │           ├───templates/
    │           │       cart.html
    │           │       header2.html
    │           │
    │           └───tests/
    │                   test_urls.py
    │                   test_views.py
    │                   __init__.py
    │
    ├───cart/
    │   │   admin.py
    │   │   apps.py
    │   │   contexts.py
    │   │   models.py
    │   │   urls.py
    │   │   views.py
    │   │   __init__.py
    │   │
    │   ├───migrations/
    │   │       __init__.py
    │   │
    │   ├───templates/
    │   │       cart.html
    │   │       header2.html
    │   │
    │   └───tests/
    │           test_urls.py
    │           test_views.py
    │           __init__.py
    │
    ├───cart.egg-info/
    │       dependency_links.txt
    │       PKG-INFO
    │       SOURCES.txt
    │       top_level.txt
    │
    └───dist/
            cart-0.0.1-py3-none-any.whl
            cart-0.0.1.tar.gz
    Bash

    Instalando Seu Proprio Pacote Django

    O próximo passo para usar seu pacote é enviá-lo para um repositório do github para ser usado por você ou sua empresa.

    Então, você pode instalar o pacote pelo seguinte comando:

    Para repositório privado:

    pip install git+ssh://git@github.com:sua_conta/seu_pacote_django.git
    Bash

    Para repositório público:

    pip install git+https://github.com/sua_conta/seu_pacote_django.git
    Bash

    Faça uma pip list para verificar se o pacote do carrinho está instalado no seu ambiente virtual.

    $ pip list
    Package    Version
    ---------- -------
    pip        21.2.4
    cart        0.0.1   <-- Aqui
    Bash

    Portanto, seguindo este tutorial você aprendeu como construir seu próprio pacote Django que pode ser reutilizado entre diferentes projetos. Por último, mas não menos importante, embora este tutorial tenha exemplificado um aplicativo Django que foi transformado em um pacote, esta abordagem que você aprendeu tem o mesmo processo para criar qualquer pacote Python.

  • Entendendo Estruturas de Controle em JavaScript: Condições e Loops

    Entendendo Estruturas de Controle em JavaScript: Condições e Loops

    Ao iniciar seus estudos de programação, é crucial compreender as estruturas de controle, fundamentais para guiar o fluxo de execução do código.

    Em uma visão panorâmica, essas estruturas são as responsáveis por tomar decisões e repetir ações, conferindo ao desenvolvedor o poder de moldar o comportamento do programa.

    A necessidade de direcionar o fluxo de execução surge da complexidade inerente aos problemas que enfrentamos na programação.

    Ao compreender a importância dessas estruturas, desenvolvedores ganham ferramentas para criar lógicas flexíveis e eficientes, essenciais para qualquer aplicação robusta.

    Vamos, portanto, explorar de forma pragmática como as estruturas de controle se tornam a espinha dorsal de qualquer código significativo.

    Condições em JavaScript: Tomando Decisões no Código

    Na industria de desenvolviment web e de software, a capacidade de tomar decisões é crucial. As estruturas condicionais em JavaScript oferecem uma maneira eficiente de moldar o comportamento do código, permitindo que certas instruções sejam executadas apenas se determinadas condições forem atendidas.

    Vamos começar explorando o básico com a estrutura if. Este é o bloco fundamental de uma condição. Se a expressão dentro do if avaliar como verdadeira, o bloco de código associado será executado.

    let idade = 18;
    
    if (idade >= 18) {
        console.log("Pode votar!"); // Este bloco será executado se a idade for maior ou igual a 18  
    }
    JavaScript

    Em seguida, introduzimos o else if, que permite verificar condições adicionais se a primeira expressão for falsa.

    let horaAtual = 14;
    
    if (horaAtual < 12) {
        console.log("Bom dia!");
    } else if (horaAtual < 18) {
        console.log("Boa tarde!");
    } else {
        console.log("Boa noite!");
    }
    JavaScript

    O bloco de código dentro do primeiro if será executado se a horaAtual for menor que 12. Se não for, mas for menor que 18, o bloco dentro do else if será executado. Caso contrário, o bloco dentro do else será a escolha.

    As estruturas condicionais fornecem a flexibilidade necessária para lidar com diferentes cenários, tornando o código mais adaptável e responsivo. No entanto, é fundamental usá-las com moderação para evitar complexidades desnecessárias.

    Loops em JavaScript: Repetindo Ações com Eficiência

    Em muitos cenários de programação, a repetição de ações é uma necessidade comum. Os loops em JavaScript fornecem uma maneira eficiente de executar instruções repetidas vezes. Existem diferentes tipos de loops, cada um com sua aplicação específica.

    Comecemos com o loop for, que é amplamente utilizado quando se sabe antecipadamente quantas iterações serão necessárias.

    for (let i = 0; i < 5; i++) {
        console.log(`Iteração ${i + 1}`);
    }
    JavaScript

    Neste exemplo, o loop for executará cinco iterações, imprimindo cada uma no console. A estrutura (inicialização; condição; incremento) controla o comportamento do loop.

    O loop while, por outro lado, é adequado quando a condição de parada não é conhecida antecipadamente, e as iterações continuam enquanto a condição especificada for verdadeira.

    let contador = 0;
    
    while (contador < 3) {
        console.log(`Iteração ${contador + 1}`);
        contador++;
    }
    JavaScript

    No exemplo acima, o loop while continuará executando até que o contador atinja o valor de 3. A condição é verificada antes de cada iteração.

    https://wordpress.vps9144.panel.icontainer.cloud/introducao-ao-javascript-fundamentos-basicos-para-iniciantes/

    Por fim, o loop do-while é semelhante ao while, mas garante que o bloco de código seja executado pelo menos uma vez, mesmo se a condição for inicialmente falsa.

    let numero;
    do {
        numero = prompt("Digite um número maior que 5:");
    } while (numero <= 5);
    
    console.log(`Você digitou ${numero}`);
    JavaScript

    Este exemplo solicita ao usuário para digitar um número maior que 5. O código será executado pelo menos uma vez, garantindo a interação do usuário.

    Ao entender e aplicar corretamente os loops, os desenvolvedores podem otimizar a execução de tarefas repetitivas, contribuindo para a eficiência e legibilidade do código.

    Voce tambem pode acompanhar mais turorias neste link aqui.

    Switch: Simplificando Condições Múltiplas

    Quando há a necessidade de avaliar uma expressão em relação a múltiplos casos, a estrutura switch em JavaScript oferece uma alternativa eficiente e legível. Esta construção é especialmente útil quando há várias condições possíveis e uma ação específica deve ser executada com base no valor da expressão.

    Vejamos um exemplo prático de uso do switch para determinar a estação do ano com base no número do mês:

    let mes = 6;
    let estacao;
    
    switch (mes) {
        case 12:
        case 1:
        case 2:
            estacao = "Inverno";
            break;
        case 3:
        case 4:
        case 5:
            estacao = "Primavera";
            break;
        case 6:
        case 7:
        case 8:
            estacao = "Verão";
            break;
        case 9:
        case 10:
        case 11:
            estacao = "Outono";
            break;
        default:
            estacao = "Mês inválido";
    }
    
    console.log(`Estamos na estação: ${estacao}`);
    // Resultado:
    // Estamos na estação Verão
    JavaScript

    este exemplo, a variável mes é avaliada pelo switch, e diferentes blocos de código são executados com base no valor do mês. Note a utilização de break ao final de cada caso para evitar a execução dos casos subsequentes.

    O switch simplifica significativamente blocos de condicionais que envolvem múltiplos casos, proporcionando um código mais limpo e fácil de entender.

    Conclusão

    Em resumo, as estruturas de controle em JavaScript são a espinha dorsal do desenvolvimento de software.

    Elas capacitam os programadores a direcionar o fluxo de execução, tomar decisões e repetir ações de maneira eficiente. Compreender profundamente essas estruturas é essencial para criar códigos robustos e lógicas flexíveis.

    A moderação ao utilizar construções condicionais e loops é a chave para evitar complexidades desnecessárias. Em última análise, ao dominar essas ferramentas, os desenvolvedores podem elevar significativamente a qualidade e eficiência de seus códigos em JavaScript.

  • Erros e Exceções em JavaScript: Lidando com Problemas e Depuração de Código

    Erros e Exceções em JavaScript: Lidando com Problemas e Depuração de Código

    Na prática da programação, a ocorrência de erros é inevitável.

    Compreender a natureza desses equívocos e a sua relevância é fundamental para o desenvolvimento de código robusto e confiável.

    Neste contexto, exploraremos a natureza dos erros em JavaScript, destacando a importância de uma abordagem estruturada no tratamento de situações inesperadas.

    Vamos adentrar nesse cenário desafiador, onde a gestão eficaz de erros se torna essencial para a construção de sistemas resilientes.

    Principais Tipos de Erros em JavaScript

    Ao lidar com a imprevisibilidade do desenvolvimento em JavaScript, é imperativo compreender não apenas os tipos de erros que podem surgir, mas também como implementar estratégias eficazes para tratá-los. Nesta seção, exploraremos métodos para mitigar impactos negativos de erros, proporcionando uma experiência mais robusta para os usuários finais.

    O Uso Consciente de Try-Catch

    Uma das ferramentas fundamentais no arsenal de um desenvolvedor JavaScript é a estrutura try-catch. Esta abordagem permite que blocos de código sejam testados quanto a erros enquanto fornecem um mecanismo de recuperação quando algo inesperado acontece.

    try {
        // Código suscetível a erros
        const resultado = funcaoNaoDefinida(); // Exemplo de ReferenceError
        console.log(resultado);
    } catch (erro) {
        // Ação a ser tomada em caso de erro
        console.error(`O seguinte erro ocorreu: ${erro.message}`);
    }
    JavaScript

    No exemplo acima, a função funcaoNaoDefinida não está declarada, resultando em um ReferenceError. O bloco catch entra em ação, permitindo-nos tratar o erro de maneira controlada, evitando a interrupção abrupta do programa.

    Blocos Finally e a Limpeza de Recursos

    Introduzido juntamente com try e catch, o bloco finally é utilizado para definir ações que sempre serão executadas, independentemente de ocorrerem ou não erros no bloco try. Isso é particularmente útil quando se trata de liberar recursos ou realizar tarefas de limpeza

    let recurso;
    
    try {
        recurso = iniciarRecurso();
        // Código que pode gerar erros
    } catch (erro) {
        console.error(`O seguinte erro ocorreu: ${erro.message}`);
    } finally {
        // Ação a ser executada independentemente de erros
        encerrarRecurso(recurso);
    }
    JavaScript

    No exemplo, mesmo se um erro ocorrer durante a execução do bloco try, o recurso será adequadamente encerrado no bloco finally, prevenindo vazamentos de recursos.

    Personalizando Exceções com throw

    Além de capturar erros, JavaScript permite que desenvolvedores emitam suas próprias exceções usando a instrução throw. Isso possibilita sinalizar situações excepcionais específicas no código.

    function validarEntrada(usuario) {
      if (!usuario.nome || !usuario.email) {
        throw new Error('Nome e email são obrigatórios.'); 
      }
    // Lógica adicional
    }
    JavaScript

    Neste exemplo, a função validarEntrada lança um erro personalizado se as propriedades nome ou email estiverem ausentes no objeto usuario.

    Caso precise seguir mais tutoriais te convido a visitar nossas ultimas postagens

    Exceções Personalizadas em JavaScript

    Em situações onde as exceções padrão podem não capturar adequadamente a complexidade de um erro, criar exceções personalizadas torna-se uma prática valiosa. Vamos explorar como isso pode ser alcançado em JavaScript, oferecendo uma abordagem mais refinada ao tratamento de erros.

    Definindo Exceções Personalizadas

    A criação de exceções personalizadas envolve a definição de novas classes que estendem a classe Error nativa do JavaScript. Essas classes podem incluir informações adicionais sobre o erro, proporcionando uma compreensão mais profunda quando uma exceção é lançada.

    class ExcecaoUsuarioNaoEncontrado extends Error {
        constructor(usuarioId) {
            super(`Usuário com ID ${usuarioId} não encontrado.`);
            this.name = 'ExcecaoUsuarioNaoEncontrado';
        }
    }
    
    // Uso da exceção personalizada
    function encontrarUsuario(usuarioId) {
        // Lógica para encontrar usuário
        if (!usuarioEncontrado) {
            throw new ExcecaoUsuarioNaoEncontrado(usuarioId);
        }
        // Restante da lógica
    }
    JavaScript

    No exemplo acima, a classe ExcecaoUsuarioNaoEncontrado é uma exceção personalizada que inclui o ID do usuário na mensagem de erro. Quando essa exceção é lançada, ela fornece informações específicas sobre o contexto do erro.

    Vantagens de Exceções Personalizadas

    1. Clareza Semântica: Exceções personalizadas têm o poder de comunicar a natureza específica do erro, facilitando a identificação e correção.
    2. Gestão Hierárquica de Erros: Ao organizar exceções personalizadas em uma hierarquia, é possível capturar categorias amplas de erros ou lidar com casos específicos de maneira granular.
    3. Rastreamento Aprimorado: Mensagens de erro mais detalhadas e rastreamento aprimorado ajudam os desenvolvedores a localizar a origem do problema com mais eficácia.

    Integração com Tratamento de Erros

    O uso efetivo de exceções personalizadas geralmente está atrelado a uma estratégia robusta de tratamento de erros. Ao combinar o lançamento de exceções personalizadas com blocos try-catch, é possível criar uma experiência de desenvolvimento mais resiliente.

    try {
        encontrarUsuario(123);
    } catch (erro) {
        if (erro instanceof ExcecaoUsuarioNaoEncontrado) {
            console.error(`Erro: ${erro.message}`);
            // Lógica específica para usuário não encontrado
        } else {
            console.error('Erro inesperado:', erro);
        }
    }
    JavaScript

    Ao abraçar exceções personalizadas, os desenvolvedores têm em mãos uma ferramenta poderosa para modelar erros de maneira mais significativa, promovendo uma abordagem mais proativa na gestão de falhas em seus aplicativos.

    Conclusão

    Em meio à complexidade do desenvolvimento de software, a habilidade de lidar eficazmente com erros torna-se crucial para a criação de aplicativos robustos e resilientes. Ao explorar as exceções personalizadas em JavaScript, revelamos uma ferramenta poderosa nas mãos dos desenvolvedores.

    Adotar exceções personalizadas não é apenas uma prática técnica; é uma abordagem que transcende a simples detecção de erros. Proporciona clareza semântica ao código, permitindo que mensagens de erro transmitam não apenas a presença de um problema, mas também sua natureza específica.

    A vantagem de criar exceções personalizadas reside na capacidade de modelar erros de maneira mais significativa. Essas exceções não são apenas mensagens de falha; são veículos de informação, oferecendo insights detalhados sobre o contexto do erro. Essa riqueza de detalhes não só simplifica a identificação da fonte do problema, mas também acelera o processo de resolução.

    Ao integrar exceções personalizadas em uma estratégia abrangente de tratamento de erros, os desenvolvedores podem adotar uma abordagem mais proativa na gestão de falhas em seus aplicativos. Mais ainda, a gestão hierárquica de erros permite uma resposta adaptativa, direcionando esforços para situações específicas ou lidando eficientemente com categorias mais amplas de erros.

    Portanto, concluímos que as exceções personalizadas não são apenas um recurso técnico; são aliadas na busca por códigos mais claros, resilientes e de alta qualidade. Ao abraçar essa prática, os desenvolvedores capacitam-se a enfrentar os desafios do desenvolvimento de software com confiança, construindo aplicações que não apenas funcionam, mas elevam os padrões de excelência.

  • Explorando Estruturas de Dados em JavaScript: Mais do que Apenas Arrays

    Explorando Estruturas de Dados em JavaScript: Mais do que Apenas Arrays

    Em um cenário cada vez mais digital, a habilidade de manipular dados de forma eficiente torna-se vital para os desenvolvedores. No ecossistema de linguagens de programação, o JavaScript destaca-se como uma escolha proeminente, oferecendo uma ampla gama de estruturas de dados para organizar e gerenciar informações.

    Este artigo se adentra nos conceitos das estruturas de dados em JavaScript, guiando desde os conceitos fundamentais até nuances mais avançadas. Ao compreender como utilizar objetos, arrays e outras estruturas, os desenvolvedores estarão melhor equipados para criar aplicações dinâmicas e responsivas.

    Vamos explorar não apenas as bases, mas também a aplicação prática desses conceitos em cenários do mundo real. Ao final desta jornada, os leitores terão uma visão aprofundada de como otimizar a manipulação de dados em seus projetos JavaScript

    Arrays: Fundação da Organização

    Os arrays em JavaScript são uma peça fundamental no desenvolvimento de aplicações, oferecendo uma maneira poderosa e flexível de organizar dados.

    // Exemplo de arrays simples
    let frutas = ["maçã", "pera","morango"]
    JavaScript

    Porem, suponha que você esteja construindo um sistema de agenda e precise armazenar informações sobre diversos eventos.

    Um array é uma escolha ideal para representar uma coleção desses eventos. Abaixo, temos um exemplo que utiliza um array para armazenar informações sobre reuniões, workshops e almoços.

    let eventos = [
        {
            titulo: 'Reunião de Projeto',
            data: '2022-02-15',
            hora: '14:00',
            local: 'Sala de Conferências'
        },
        {
            titulo: 'Workshop de JavaScript',
            data: '2022-02-20',
            hora: '10:00',
            local: 'Auditório'
        },
        {
            titulo: 'Almoço com Cliente',
            data: '2022-02-25',
            hora: '12:30',
            local: 'Restaurante'
        }
    ];
    
    JavaScript

    Neste exemplo, cada evento é um objeto com propriedades como título, data, hora e local. Para acessar individualmente os eventos, utilizamos índices do array. Por exemplo, eventos[0] representa a primeira reunião da lista.

    Para realizar tarefas mais complexas, como listar eventos agendados para o próximo mês, podemos usar estruturas de controle de fluxo, como loops. O código a seguir mostra como filtrar eventos com base na data.

    let eventosProximoMes = [];
    
    for (let i = 0; i < eventos.length; i++) {
        let dataEvento = new Date(eventos[i].data);
        
        // Comparando se a data do evento é do próximo mês
        if (dataEvento.getMonth() === new Date().getMonth() + 1) {
            eventosProximoMes.push(eventos[i]);
        }
    }
    
    console.log(eventosProximoMes);
    // Saída: [{...}, {...}] // Eventos do próximo mês
    
    JavaScript

    Esta abordagem demonstra como os arrays podem ser usados para organizar dados complexos e como suas propriedades podem ser acessadas.

    Objetos No JavaScript: Expansão do Poder com Propriedades e Métodos

    Agora que entendemos a fundação dos arrays, é hora de adentrar uma extensão poderosa dessa ideia: objetos em JavaScript. Os objetos permitem organizar dados de forma estruturada, usando propriedades e métodos para representar características e comportamentos.

    Vamos considerar a continuação do exemplo da agenda, onde queremos adicionar mais detalhes aos eventos, como participantes e status. Usando objetos, podemos modelar essa informação de maneira mais rica.

    let eventosDetalhados = [
        {
            titulo: 'Reunião de Projeto',
            data: '2022-02-15',
            hora: '14:00',
            local: 'Sala de Conferências',
            participantes: ['João', 'Maria', 'Carlos'],
            status: 'Confirmado'
        },
        {
            titulo: 'Workshop de JavaScript',
            data: '2022-02-20',
            hora: '10:00',
            local: 'Auditório',
            participantes: ['Ana', 'José'],
            status: 'Confirmado'
        },
        {
            titulo: 'Almoço com Cliente',
            data: '2022-02-25',
            hora: '12:30',
            local: 'Restaurante',
            participantes: ['Camila', 'Daniel'],
            status: 'Pendente'
        }
    ];
    JavaScript

    Agora, cada evento é representado como um objeto com propriedades adicionais, como participantes e status. Podemos acessar essas informações usando a notação de ponto, por exemplo, eventosDetalhados[0].participantes retorna a lista de participantes da primeira reunião.

    Além disso, podemos criar métodos para executar ações específicas relacionadas aos eventos. Por exemplo, podemos criar um método para verificar se um evento está confirmado.

    let evento = {
        titulo: 'Reunião de Projeto',
        data: '2022-02-15',
        hora: '14:00',
        local: 'Sala de Conferências',
        participantes: ['João', 'Maria', 'Carlos'],
        status: 'Confirmado',
        estaConfirmado: function () { // <--------- AQUI
            return this.status === 'Confirmado';
        }
    };
    
    console.log(evento.estaConfirmado());
    // Saída: true
    JavaScript

    No exemplo acima, estaConfirmado é um método que retorna true se o status do evento for ‘Confirmado’. Essa flexibilidade na definição de propriedades e métodos torna os objetos uma ferramenta poderosa para modelar dados em JavaScript.

    Caso você queira entender o basico de JavaScript e seu papel no desenvolviemento web eu te indico a ler este artigo.

    Controle de Fluxo com Objetos: Tomando Decisões e Repetindo Ações

    Agora que compreendemos a estrutura dos objetos em JavaScript, é crucial entender como aplicar estruturas de controle de fluxo a eles. O controle de fluxo refere-se à capacidade de tomar decisões e repetir ações com base em condições específicas.

    Vamos considerar um cenário em que queremos verificar se um evento possui participantes antes de realizar uma ação. Aqui, usaremos uma estrutura condicional if junto com um objeto.

    let evento = {
        titulo: 'Reunião de Projeto',
        data: '2022-02-15',
        hora: '14:00',
        local: 'Sala de Conferências',
        participantes: ['João', 'Maria', 'Carlos'],
        status: 'Confirmado',
        realizarAcao: function () {
            if (this.participantes.length > 0) {
                console.log('Ação realizada!');
            } else {
                console.log('Nenhum participante confirmado. Ação não realizada.');
            }
        }
    };
    
    evento.realizarAcao();
    // Saída: Ação realizada!
    
    JavaScript

    No exemplo acima, o método realizarAcao verifica se existem participantes no evento antes de executar a ação. Essa é uma maneira simples de aplicar lógica condicional a objetos.

    Da mesma forma, podemos usar loops para iterar sobre propriedades de objetos. Vamos considerar um exemplo em que queremos listar todos os participantes de um evento.

    let evento = {
        titulo: 'Reunião de Projeto',
        data: '2022-02-15',
        hora: '14:00',
        local: 'Sala de Conferências',
        participantes: ['João', 'Maria', 'Carlos'],
        status: 'Confirmado',
        listarParticipantes: function () {
            console.log('Participantes do Evento:');
            for (let participante of this.participantes) {
                console.log(participante);
            }
        }
    };
    
    evento.listarParticipantes();
    // Saída:
    // Participantes do Evento:
    // João
    // Maria
    // Carlos
    
    JavaScript

    Neste caso, o método listarParticipantes utiliza um loop for...of para percorrer a lista de participantes e exibi-los no console.

    Essas estruturas de controle de fluxo são essenciais ao trabalhar com objetos, permitindo que você crie lógicas mais dinâmicas e responsivas.

    Conclusão

    Em programação, a eficiente manipulação de dados é crucial, e o JavaScript oferece uma gama robusta de ferramentas para essa finalidade. Este artigo proporcionou uma visão abrangente das estruturas de dados, desde as básicas até conceitos mais avançados.

    Exploramos a fundação com estruturas fundamentais como objetos, strings, números e booleanos. Aprofundamos nosso entendimento, explorando nuances e aplicações específicas que tornam essas estruturas poderosas em contextos diversos.

    A seção sobre arrays destacou sua importância na organização de dados, usando exemplos práticos, como um sistema de agenda. Demonstrações de como filtrar eventos com base em datas e a flexibilidade dos arrays na manipulação de informações complexas foram abordadas.

    Em seguida, mergulhamos nos objetos, que expandem significativamente a capacidade de modelagem de dados. Criar funções de construção, métodos prototipados e utilizar a desestruturação de objetos foram conceitos fundamentais explorados. O exemplo da agenda evoluiu para incluir detalhes como participantes e status.

    A seção sobre controle de fluxo aplicado a objetos destacou como estruturas condicionais e loops podem ser incorporados para tomar decisões dinâmicas e repetir ações com base nas propriedades dos objetos. Isso se mostrou vital para criar lógicas mais responsivas e interativas.

    Em suma, a jornada de explorar estruturas de dados em JavaScript não apenas amplia a compreensão dos conceitos básicos, mas capacita os desenvolvedores a construir aplicações mais robustas e dinâmicas. O aprendizado contínuo e a experimentação são essenciais para dominar completamente essas ferramentas e aprimorar as habilidades de desenvolvimento em JavaScript.

  • Introdução ao JavaScript: Fundamentos Básicos para Iniciantes

    Introdução ao JavaScript: Fundamentos Básicos para Iniciantes

    JavaScript, uma linguagem de programação dinâmica e orientada a objetos, desempenha um papel essencial no desenvolvimento web inicialmente no frontend.

    Ultilizada por milhares de desenvolvedores esta linguagem de programação veio para ficar e e essencial no desenvolvimento web.

    Alem do mais, o JavaScript transcendeu seu papel original no front-end e expandiu sua presença para o back-end com a introdução do Node.js, tornando-se uma escolha essencial para o desenvolvimento web completo.

    Desde validações de formulários até atualizações dinâmicas de conteúdo, JavaScript é a força por trás da interatividade em diversas páginas web.

    Implementada conforme o padrão ECMAScript, JavaScript passou por várias evoluções ao longo do tempo, incorporando melhorias significativas e mantendo-se alinhada com os padrões da indústria.

    A versatilidade de JavaScript não se limita apenas ao desenvolvimento web. Sua presença é notável no desenvolvimento móvel, integração com APIs, criação de aplicativos backend com Node.js, e até mesmo na construção de jogos e gráficos complexos.

    Sendo assim, nesta postagem irei falar sobre o que você entender para começar nesta linguagem de programação tão famosa que é o JavaScript.

    Contextualização da Utilização do JavaScript

    Contextualização de Utilização do JavaScript

    O JavaScript tornou-se uma linguagem essencial em várias áreas de desenvolvimento de software, desempenhando papéis cruciais em diferentes cenários.

    Desenvolvimento Front-end:

    • Interação com o Navegador: JavaScript é a linguagem principal para tornar páginas da web dinâmicas e interativas, permitindo manipulação de elementos HTML e resposta a eventos do usuário.
    • Frameworks Front-end: Muitos frameworks, como React, Angular e Vue.js, são construídos com JavaScript, simplificando o desenvolvimento de interfaces de usuário avançadas.

    Desenvolvimento Back-end com Node.js:

    • Servidor JavaScript: Com o Node.js, JavaScript transcende o navegador e se torna uma linguagem de servidor. Você pode construir aplicativos back-end robustos usando a mesma linguagem em ambos os lados.
    • Gestão de Pacotes: O npm (Node Package Manager) facilita a instalação e gerenciamento de bibliotecas e ferramentas no desenvolvimento back-end.

    Aplicações Móveis:

    • React Native: Para desenvolvimento de aplicativos móveis, o JavaScript é utilizado com o React Native, permitindo a criação de aplicativos nativos para iOS e Android.

    Automação de Tarefas:

    • Node.js e Gulp/Grunt: JavaScript é amplamente empregado para automatizar tarefas no desenvolvimento, como minificação de código, otimização de imagens e construção de projetos.

    Jogos e Aplicações de Desktop:

    • Electron: Usando o framework Electron, você pode criar aplicativos de desktop usando tecnologias web padrão (HTML, CSS, JavaScript).

    Integração com APIs:

    • Consumo e Criação: JavaScript é essencial para consumir APIs externas em aplicativos e para criar suas próprias APIs no lado do servidor.

    Internet das Coisas (IoT):

    • Plataforma para IoT: Com a versatilidade do JavaScript, é possível desenvolver aplicativos para dispositivos IoT.

    Sintaxe Básica do JavaScript

    Embora o JavaScript tenha todas essas funções e preciso aprender o basico da mesma para que possamos entender o contexto de cada area que o JavaScript funciona.

    Sendo assim, a compreensão da sintaxe básica do JavaScript é fundamental para construir programas eficazes. Nesta seção, vamos ver os principais elementos que formam a estrutura fundamental da linguagem.

    Variáveis e Constantes

    No exemplo abaixo temos a base de qualquer linguagem de programação as variaveis. Para que voce entenda melhor, as variaveis são como containers, que recebem um tipo de dados.

    Ex: idade recebe o numero 25.

    /* ----- Declaração e atribuição ----- */
    // Usando 'var' (escopo global ou de função)
    var idade = 25;
    
    // Usando 'let' (escopo de bloco)
    let nome = "João";
    
    // Usando 'const' (constante, não pode ser reatribuída)
    const pi = 3.14;
    
    /* ----- Convenções de Nomenclatura -----*/
    // Camel Case
    let nomeDoUsuario = "Alice";
    
    // Snake Case
    const preco_produto = 20.99;
    
    JavaScript

    Tipo de dados no JavaScript

    Assim como as variaveis são importante para as linguagens de programação a mesma coisa seriam os tipos de dados. Para que voce entenda melhor, os tipos de dados são diferente um dos outros para que podemos manipula-los de acordo. A string (conjunto de letras) serve para manipular e guardar textos, integer (numeros inteiros) são usados para se usar fatores numericos basico e avançados. E uma questao de logica…

    /* ----- Tipos primitivos ----- */
    let numero = 42;          // Número
    let texto = "Olá";        // String
    let condicao = true;      // Booleano
    let vazio = null;          // Nulo
    let indefinido;            // Indefinido (undefined)
    
    /* ---- Tipagem dinamica ----- */
    let mensagem = "Oi!";
    mensagem = 123; // Sem erro, a variável aceita diferentes tipos de dados.
    
    JavaScript

    Operadores

    Outro ponto importante não apenas no JavaScript mas tambem outras linguagens de programação são os operadores logicos, de atribuição e comparação.

    /* ----- Operadores Aritimeticos ----- */
    
    let soma = 10 + 5;
    let subtracao = 20 - 8;
    let multiplicacao = 5 * 4;
    let divisao = 50 / 2;
    
    /* ----- Operadores Logicos ----- */
    let verdadeiro = true;
    let falso = false;
    
    let resultadoE = verdadeiro && falso; // AND
    let resultadoOU = verdadeiro || falso; // OR
    let resultadoNao = !verdadeiro; // NOT
    
    /* ----- Operadores de Atribuição e Comparativos ----- */
    let x = 10;
    let y = 10;
    
    x += 5; // Atribuição com adição (x = x + 5)
    let igualdade = x === y; // Igualdade estrita
    let diferenca = x !== y; // Diferença estrita
    JavaScript

    Embora a maioria das linguagens de programação sigam um padrão, como o uso de variaveis, operadores, condições etc, elas tem o seu proprio estilo/sintaxe a ser seguidos. E no JavaScript não é diferente. A seguir irei mostrar em codigo como basicamente se deve seguir a sintaxe e estilo do codigo no javascript.

    Comentarios

    Mais uma vez, como o nome mesmo diz, os comentarios são usados para comentar o codigo. Essas linhas são ignoradas pelo interpretador do JavaScript. Sendo assim, voce pode usa-la para adicionar explicações para o codigo necessaria para quem ira futuramente le-lo.

    // Este é um comentário de uma linha que estou usando desde o começo :D
    
    /*
      Este é um comentário
      de múltiplas linhas
    */
    JavaScript

    Condições

    Como o nome ja diz, condicionais são usadas para trazer logica para o programa que voce esta criando. Temos o if (que significa o nosso “se”), else if (que significa “mas se”) e temos o else (que neste contexto seria o “mas”).

    Eu pessoalmente vejo o else sozinho como um “então”, onde na logica nos colocamos o codigo que deve ser alocado caso nenhuma condicional foi recebida.

    let hora = 15;
    
    if (hora < 12) {
      console.log("Bom dia!");
    } else if (hora < 18) {
      console.log("Boa tarde!");
    } else {
      console.log("Boa noite!");
    }
    JavaScript

    Loopings

    Loops ou laços são importantes para repetilção de tarefas em um programa. Existem diferente tipos de laços no JavaScript porém neste artigo irei falar apenas de dois que são o for e while loops.

    O for loop é usado para trazer ou repetir tarefas baseando-se em numeros fixos de items. Já o while loop é usado quando não sabemos o numero de iteração que o programa deve fazer. Sendo assim deixando um valor a ser retornado como true (verdadeiro) para parar sua iteração.

    for (let i = 0; i < 5; i++) {
      console.log("Número:", i);
    }
    
    let contador = 0;
    while (contador < 3) {
      console.log("Contagem:", contador);
      contador++;
    }
    JavaScript

    Funções no JavaScript

    Funções na maioria das linguagens de programação são usados como um pedaco de codigo que recebe valores e retornam outros valores ou apenas processa a informacão. Normalmente as funções são auto-descritivas, com o seu nome ja dizendo o que elas fazem. Na função exemplo abaixo uma função foi criada para saber se um usuario, baseado em sua idade pode ter acesso ao bar. E dentro da mesma podemos ver que existe uma condição no qual e necessario uma idade de no minmo de 18 anos.

    function acessoAoBar(idade){
      // checa se o usuario tem idade para acessar o bar.
      if (idade => 18){
        return true;
      }
      else {
         return false;
      }
    }
    JavaScript

    Conclusão

    Em suma, esta introdução ao JavaScript proporcionou uma compreensão fundamental dos conceitos essenciais para iniciar o desenvolvimento na linguagem.

    Exploramos desde a contextualização da ultilização do JavaScript até a sintaxe básica da linguagem, incluindo o controle de fluxo e o uso de funções.

    Além disso, discutimos a importância do JavaScript em diversos cenários de desenvolvimento, desde o front-end até o back-end com o Node.js.

    Através da exploração desses conceitos, você está bem equipado para iniciar sua jornada no desenvolvimento JavaScript.

    Ao dominar esses fundamentos, você terá uma base sólida para a construção de aplicativos web dinâmicos e interativos.

    Recomenda-se praticar e experimentar os conceitos abordados neste guia, explorando projetos simples e avançados para aprimorar suas habilidades e se tornar um desenvolvedor JavaScript mais experiente.

    Continue aprendendo, explorando e criando!