<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Giovani Fouz</title>
    <description>The latest articles on DEV Community by Giovani Fouz (@gfouz).</description>
    <link>https://dev.to/gfouz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F893736%2F6ca75795-4154-4233-887b-fd6f5cb23bf7.jpg</url>
      <title>DEV Community: Giovani Fouz</title>
      <link>https://dev.to/gfouz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gfouz"/>
    <language>en</language>
    <item>
      <title>Comprendiendo el uso del Asterisco (`*`) y Doble Asterisco (`**`) en Python</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Sat, 09 Nov 2024 11:15:03 +0000</pubDate>
      <link>https://dev.to/gfouz/comprendiendo-el-uso-del-asterisco-y-doble-asterisco-en-python-2i4e</link>
      <guid>https://dev.to/gfouz/comprendiendo-el-uso-del-asterisco-y-doble-asterisco-en-python-2i4e</guid>
      <description>&lt;p&gt;Cuando trabajamos en Python, a menudo nos encontramos con situaciones en las que necesitamos que nuestras funciones sean flexibles y capaces de manejar diferentes tipos y cantidades de argumentos. Para facilitar esto, Python ofrece dos operadores muy útiles: el asterisco simple (&lt;code&gt;*&lt;/code&gt;) y el doble asterisco (&lt;code&gt;**&lt;/code&gt;). En este post, exploraremos en detalle su funcionamiento, así como su aplicación en funciones, clases y estructuras de datos como listas y diccionarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué son las estructuras de datos en Python?
&lt;/h2&gt;

&lt;p&gt;Antes de entrar en el uso del asterisco, es importante entender qué son las estructuras de datos. En Python, las estructuras de datos son formas de organizar y almacenar datos en el programa. Las más comunes son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Listas&lt;/strong&gt;: Colecciones ordenadas que permiten elementos duplicados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuplas&lt;/strong&gt;: Similares a las listas, pero son inmutables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diccionarios&lt;/strong&gt;: Colecciones no ordenadas de pares clave-valor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estas estructuras son fundamentales para manejar datos en Python y son el contexto donde los operadores &lt;code&gt;*&lt;/code&gt; y &lt;code&gt;**&lt;/code&gt; se vuelven particularmente interesantes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usos del Asterisco Simple (&lt;code&gt;*&lt;/code&gt;)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Funciones con Argumentos Variables
&lt;/h3&gt;

&lt;p&gt;El asterisco simple se utiliza principalmente en funciones para permitir que acepten un número variable de argumentos posicionales. Esto significa que puedes pasarle cualquier cantidad de argumentos y todos serán tratados como una tupla dentro de la función.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Esto imprime: 1 2 3 4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Desempaquetado de Listas o Tuplas
También puedes usar el asterisco simple para desempaquetar elementos de una lista o tupla al pasar argumentos a una función.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Esto imprime: 1 2 3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este uso del asterisco puede ser muy conveniente cuando tienes una lista de elementos y quieres pasarlos como argumentos a otra función.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usos del Doble Asterisco (&lt;code&gt;**&lt;/code&gt;)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Funciones con Argumentos de Palabra Clave
El doble asterisco se utiliza para permitir que una función acepte un número variable de argumentos de palabra clave (nombre-valor). Dentro de la función, estos argumentos se almacenan en un diccionario.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Salida:
# name: Alice
# age: 30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Desempaquetado de Diccionarios
Al igual que el asterisco para listas y tuplas, puedes usar el doble asterisco para desempaquetar pares clave-valor desde un diccionario al llamar a una función.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Osea es lo mismo que: func(name="Alice", age=30)
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usos Avanzados de * y ** en Clases
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;

&lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# (1, 2)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# {'a': 3, 'b': 4}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En Herencia&lt;br&gt;
Puedes utilizar *args y **kwargs para pasar argumentos al constructor de la clase base, lo que permite que la clase derivada extienda el comportamiento del constructor de la clase base.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Llama al constructor de Base
&lt;/span&gt;        &lt;span class="c1"&gt;# Puedes hacer algo adicional con args y kwargs aquí
&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Derived&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combinaciones de simple y doble asterisco:&lt;br&gt;
A veces, puede ser útil combinar tanto los argumentos posicionales como los de palabra clave en tus funciones para permitir un manejo completo de los datos de entrada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mixed_args&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;mixed_args&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#Salida:
&lt;/span&gt;
&lt;span class="c1"&gt;# 1 2
# (3, 4)
# {'x': 5, 'y': 6}
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.python.org/3/tutorial/controlflow.html#defining-functions" rel="noopener noreferrer"&gt;Documentación Oficial de Python sobre Funciones&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.py4e.com" rel="noopener noreferrer"&gt;Python para Todos - Curso Gratuito&lt;/a&gt;&lt;br&gt;
&lt;a href="https://realpython.com/python-unpacking/" rel="noopener noreferrer"&gt;Real Python - Unpacking in Python&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.w3schools.com/python/python_functions.asp" rel="noopener noreferrer"&gt;W3Schools - Python Functions (Defining Functions)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumen:
&lt;/h2&gt;

&lt;p&gt;args es útil para recibir un número variable de argumentos posicionales, mientras que kwargs es útil para recibir un número variable de argumentos de palabra clave.&lt;br&gt;
Puedes usar simple y doble asterisco para desempaquetar listas/tuplas y diccionarios, respectivamente, al llamar funciones.&lt;br&gt;
Ambos operadores pueden mejorar la flexibilidad y reutilización de tu código, permitiendo funciones que manejan diferentes tipos de entradas de manera eficiente.&lt;br&gt;
Recursos Útiles&lt;/p&gt;

</description>
    </item>
    <item>
      <title>React query, hook personalizado.</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Sat, 09 Nov 2024 08:02:56 +0000</pubDate>
      <link>https://dev.to/gfouz/react-query-hook-personalizado-3a5m</link>
      <guid>https://dev.to/gfouz/react-query-hook-personalizado-3a5m</guid>
      <description>&lt;p&gt;En aplicaciones de React, es común necesitar acceder a datos de una API externa. Tradicionalmente, muchos desarrolladores utilizan métodos nativos de javascript como fetch dentro de los componentes, lo que puede llevar a problemas de administración del estado y a un manejo complicado de efectos secundarios (side effects). Aquí es donde React Query entra en juego.&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué es React Query?
&lt;/h3&gt;

&lt;p&gt;React Query es una biblioteca destinada a simplificar las operaciones de obtención y manejo de datos en React. Proporciona potentes funciones para:&lt;/p&gt;

&lt;p&gt;Efectuar solicitudes de datos de una API.&lt;br&gt;
Almacenar y sincronizar el estado de la UI con los datos.&lt;br&gt;
Realizar refetching automáticamente y gestionar cachés.&lt;br&gt;
Nuestro Hook Personalizado&lt;/p&gt;

&lt;p&gt;A continuación, veamos nuestro hook personalizado, useCustomQuery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GenericObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;QueryFunction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GenericObject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useCustomQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;queryFunction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QueryFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;queryKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isPending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;
    &lt;span class="nx"&gt;GenericObject&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;GenericObject&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;queryKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queryKey&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;queryFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;queryFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPending&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Desglose del Hook
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GenericObject y QueryFunction:
&lt;/h3&gt;

&lt;p&gt;Definimos tipos genéricos que facilitan el trabajo con objetos y funciones que realizan fetching de datos. Esto asegura que nuestro código pueda adaptarse a diferentes estructuras de datos que puedan regresar las APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  useQuery:
&lt;/h3&gt;

&lt;p&gt;Usamos el hook useQuery de React Query, que maneja automáticamente el estado de nuestras solicitudes. Proporciona propiedades útiles para manejar la carga de datos, errores y refetching.        &lt;/p&gt;

&lt;p&gt;Esto mejora la calidad del código y reduce bugs.&lt;br&gt;
Interfaces Genéricas: Utilizando interfaces genéricas, podemos definir estructuras de datos que se adaptan a diferentes situaciones. Esto hace que el código sea más reutilizable y fácil de mantener.&lt;br&gt;
Mejor Documentación: El uso de TypeScript como una herramienta de documentación proporcionada por los tipos mejora la comprensión de cómo se deben usar las funciones y qué tipo de datos se esperan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enlaces Útiles
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;React Query&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentación oficial: &lt;a href="https://react-query.tanstack.com/" rel="noopener noreferrer"&gt;TanStack Query Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Guía de inicio rápido: &lt;a href="https://react-query.tanstack.com/overview" rel="noopener noreferrer"&gt;Getting Started with React Query&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentación oficial: &lt;a href="https://www.typescriptlang.org/docs/" rel="noopener noreferrer"&gt;TypeScript Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Guía de TypeScript para React: &lt;a href="https://react-typescript-cheatsheet.netlify.app/" rel="noopener noreferrer"&gt;Using TypeScript with React&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GitHub de React Query&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repositorio oficial: &lt;a href="https://github.com/TanStack/query" rel="noopener noreferrer"&gt;TanStack Query (React Query) GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ejemplos y Tutoriales&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tutorial de RapidAPI sobre React Query: &lt;a href="https://rapidapi.com/blog/react-query/" rel="noopener noreferrer"&gt;Getting Started with React Query&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Artículo sobre los beneficios de utilizar React Query: &lt;a href="https://blog.logrocket.com/why-you-should-use-react-query-in-your-next-react-app/" rel="noopener noreferrer"&gt;Benefits of Using React Query&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusión
&lt;/h3&gt;

&lt;p&gt;Integrar un hook personalizado junto con React Query y TypeScript en tus aplicaciones React transforma la forma en que gestionas las solicitudes de datos. No sólo mejora la experiencia de desarrollo al reducir la carga de lógica de manejo de estado, sino que también enriquece la robustez y facilidad de mantenimiento de tu código.&lt;br&gt;
Espero que encuentren útil este enfoque y les animo a probarlo en sus propios proyectos. ¡Feliz codificación!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Errores Comunes de Pylint. Guía Práctica</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Mon, 27 May 2024 09:10:20 +0000</pubDate>
      <link>https://dev.to/gfouz/errores-comunes-de-pylint-guia-practica-2ko</link>
      <guid>https://dev.to/gfouz/errores-comunes-de-pylint-guia-practica-2ko</guid>
      <description>&lt;p&gt;Pylint es una herramienta de análisis estático de código que se utiliza para encontrar errores y mejorar la calidad del código Python. Sin embargo, enfrentarse a los errores que reporta puede ser desalentador, especialmente para los desarrolladores novatos. Aquí exploramos algunos de los errores más comunes que lanza Pylint, cómo resolverlos y cómo podemos beneficiarnos de estas correcciones para escribir un código más limpio y eficiente.&lt;/p&gt;

&lt;p&gt;1- C0103: Variable name "x" doesn't conform to snake_case naming style&lt;br&gt;
Error:&lt;br&gt;
Este error se produce cuando el nombre de una variable no sigue la convención de nombres en Python, que es usar snake_case.&lt;/p&gt;

&lt;p&gt;Ejemplo de código que lanza el error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solución:&lt;br&gt;
Renombrar la variable para que siga la convención snake_case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;user_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- E1101: Instance of 'class' has no 'member' member&lt;br&gt;
Error:&lt;br&gt;
Pylint no puede encontrar el atributo especificado en la instancia de la clase. Esto suele ocurrir cuando se intenta acceder a un atributo que no existe.&lt;/p&gt;

&lt;p&gt;Ejemplo de código que lanza el error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solución:&lt;br&gt;
Asegurarse de que el atributo exista en la clase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- R0913: Too many arguments (6/5)&lt;br&gt;
Error:&lt;br&gt;
Esta advertencia surge cuando una función o método tiene demasiados parámetros, lo cual puede hacer que el código sea difícil de mantener y leer.&lt;/p&gt;

&lt;p&gt;Ejemplo de código que lanza el error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solución:&lt;br&gt;
Reducir el número de parámetros, por ejemplo, utilizando un diccionario o una clase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="n"&gt;user_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;johndoe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;12345&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;john@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Doe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;create_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4- W0611: Unused 'import'&lt;br&gt;
Error:&lt;br&gt;
Este error aparece cuando hay una importación en el código que no se utiliza, lo que puede añadir desorden innecesario.&lt;/p&gt;

&lt;p&gt;Ejemplo de código que lanza el error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solución:&lt;br&gt;
Eliminar las importaciones no utilizadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5- C0301: Line too long (82/80)&lt;br&gt;
Error:&lt;br&gt;
Este error se produce cuando una línea de código supera la longitud máxima recomendada de 80 caracteres.&lt;/p&gt;

&lt;p&gt;Ejemplo de código que lanza el error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Welcome to the platform. We hope you have a great experience here!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solución:&lt;br&gt;
Dividir la línea larga en varias líneas más cortas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Welcome to the platform. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;We hope you have a great experience here!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conclusión:&lt;/p&gt;

&lt;p&gt;Abordar y resolver los errores que Pylint destaca puede parecer un desafío, pero es un paso crucial hacia la mejora continua y la profesionalización de nuestro código. Cada corrección que hacemos nos acerca a un código más limpio, más eficiente y más fácil de mantener. Acepta los mensajes de Pylint como oportunidades de aprendizaje y crecimiento profesional.&lt;/p&gt;

&lt;p&gt;Para más detalles, puedes consultar la documentación oficial de Pylint que proporciona una guía exhaustiva sobre cómo interpretar y resolver los mensajes de error.&lt;/p&gt;

&lt;p&gt;Mantén la motivación y recuerda: escribir un buen código no es solo una habilidad técnica, sino también un arte que se perfecciona con práctica y perseverancia. ¡Sigue adelante y convierte cada error en un aprendizaje!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>¿Morirá React como jQuery?</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Sun, 26 May 2024 21:35:15 +0000</pubDate>
      <link>https://dev.to/gfouz/morira-react-como-jquery-13bl</link>
      <guid>https://dev.to/gfouz/morira-react-como-jquery-13bl</guid>
      <description>&lt;p&gt;En el dinámico mundo del desarrollo web, las tecnologías van y vienen. jQuery, una vez la herramienta preferida para la manipulación del DOM y la gestión de eventos, ha sido en gran medida eclipsada por la evolución del lenguaje JavaScript y la aparición de frameworks más modernos. Esto plantea una cuestión pertinente: ¿podría React, la popular biblioteca de JavaScript para construir interfaces de usuario, eventualmente sufrir el mismo destino? Analicemos esta pregunta en detalle.&lt;/p&gt;

&lt;h2&gt;
  
  
  La Historia de jQuery
&lt;/h2&gt;

&lt;p&gt;Para comprender si React podría seguir el mismo camino que jQuery, es esencial entender primero cómo jQuery alcanzó su apogeo y posterior declive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ascenso de jQuery:
&lt;/h2&gt;

&lt;p&gt;Simplificación del DOM: En sus inicios, la manipulación del DOM y la gestión de eventos eran tareas tediosas y llenas de inconsistencias entre navegadores. jQuery ofreció una API sencilla y uniforme que facilitó estas tareas.&lt;br&gt;
Compatibilidad Cross-Browser: jQuery resolvía muchos problemas de compatibilidad entre navegadores, una de las mayores dificultades para los desarrolladores web de la época.&lt;br&gt;
Extensibilidad y Plugins: jQuery ofrecía un sistema de plugins robusto, permitiendo a los desarrolladores añadir funcionalidades adicionales con facilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declive de jQuery:
&lt;/h2&gt;

&lt;p&gt;Evolución del JavaScript Nativo: Con la llegada de ECMAScript 5 y, posteriormente, ECMAScript 6 (ES6), muchas de las funcionalidades que jQuery proporcionaba se integraron directamente en el lenguaje.&lt;br&gt;
Nuevos Frameworks y Bibliotecas: Frameworks como Angular, React y Vue ofrecieron soluciones más completas y modernas para la creación de aplicaciones web, reduciendo la necesidad de jQuery.&lt;br&gt;
Mejora de los Navegadores: Los navegadores modernizaron sus API, reduciendo las inconsistencias y, por ende, la necesidad de una biblioteca como jQuery para gestionar estas diferencias.&lt;br&gt;
La Situación Actual de React&lt;br&gt;
React, lanzado por Facebook en 2013, se ha convertido en una de las bibliotecas más populares para la construcción de interfaces de usuario, gracias a varias características clave:&lt;/p&gt;

&lt;p&gt;Componentización: React introdujo el concepto de componentes reutilizables, facilitando la gestión de interfaces complejas.&lt;br&gt;
Virtual DOM: React utiliza un DOM virtual para minimizar las operaciones costosas en el DOM real, mejorando el rendimiento.&lt;/p&gt;

&lt;p&gt;Ecosistema y Herramientas: React cuenta con un ecosistema robusto, incluyendo herramientas como Redux para la gestión del estado, y Next.js para el renderizado del lado del servidor.&lt;br&gt;
Adopción y Soporte Empresarial: Grandes empresas han adoptado React, lo que garantiza su soporte continuo y evolución.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Podría React Volverse Obsoleto?
&lt;/h2&gt;

&lt;p&gt;Aunque React goza de una popularidad y uso extensivo en la actualidad, no es invulnerable a los cambios y avances tecnológicos. Aquí algunos factores que podrían influir en su futuro:&lt;/p&gt;

&lt;h2&gt;
  
  
  Emergencia de Nuevas Tecnologías:
&lt;/h2&gt;

&lt;p&gt;Tecnologías más recientes podrían surgir con paradigmas de desarrollo más eficientes. Por ejemplo, Svelte es un framework que compila el código a JavaScript puro, eliminando la necesidad de un virtual DOM.&lt;br&gt;
Evolución del Lenguaje y Estándares Web:&lt;/p&gt;

&lt;p&gt;Si el lenguaje JavaScript y los estándares web continúan evolucionando, podrían integrar de forma nativa muchas de las funcionalidades que actualmente proporcionan bibliotecas como React. Esto podría hacer que los desarrolladores prefieran soluciones nativas más ligeras.&lt;br&gt;
Competencia de Otros Frameworks:&lt;/p&gt;

&lt;p&gt;Frameworks competidores como Vue.js y Angular siguen evolucionando y ofreciendo características únicas que podrían atraer a los desarrolladores. También, frameworks como Solid.js y Qwik, que promueven un rendimiento y eficiencia superiores, podrían ganar terreno.&lt;br&gt;
Saturación del Ecosistema:&lt;/p&gt;

&lt;p&gt;La complejidad creciente del ecosistema de React, con la proliferación de librerías y herramientas adicionales, podría desanimar a los nuevos desarrolladores y conducirlos a buscar alternativas más simples.&lt;/p&gt;

&lt;p&gt;Conclusión&lt;/p&gt;

&lt;p&gt;En resumen, mientras que es difícil predecir con certeza el futuro de cualquier tecnología, la trayectoria de jQuery ofrece lecciones valiosas. React, con su fuerte adopción y apoyo comunitario, está bien posicionado para permanecer relevante en el futuro cercano. Sin embargo, la continua evolución del desarrollo web significa que siempre habrá nuevas tecnologías y paradigmas que podrían desplazar a las herramientas actuales. La clave para la longevidad de React residirá en su capacidad para adaptarse e innovar frente a estos cambios constantes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>¿Morirá React como jQuery?</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Sun, 26 May 2024 21:34:58 +0000</pubDate>
      <link>https://dev.to/gfouz/morira-react-como-jquery-31ce</link>
      <guid>https://dev.to/gfouz/morira-react-como-jquery-31ce</guid>
      <description>&lt;p&gt;En el dinámico mundo del desarrollo web, las tecnologías van y vienen. jQuery, una vez la herramienta preferida para la manipulación del DOM y la gestión de eventos, ha sido en gran medida eclipsada por la evolución del lenguaje JavaScript y la aparición de frameworks más modernos. Esto plantea una cuestión pertinente: ¿podría React, la popular biblioteca de JavaScript para construir interfaces de usuario, eventualmente sufrir el mismo destino? Analicemos esta pregunta en detalle.&lt;/p&gt;

&lt;h2&gt;
  
  
  La Historia de jQuery
&lt;/h2&gt;

&lt;p&gt;Para comprender si React podría seguir el mismo camino que jQuery, es esencial entender primero cómo jQuery alcanzó su apogeo y posterior declive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ascenso de jQuery:
&lt;/h2&gt;

&lt;p&gt;Simplificación del DOM: En sus inicios, la manipulación del DOM y la gestión de eventos eran tareas tediosas y llenas de inconsistencias entre navegadores. jQuery ofreció una API sencilla y uniforme que facilitó estas tareas.&lt;br&gt;
Compatibilidad Cross-Browser: jQuery resolvía muchos problemas de compatibilidad entre navegadores, una de las mayores dificultades para los desarrolladores web de la época.&lt;br&gt;
Extensibilidad y Plugins: jQuery ofrecía un sistema de plugins robusto, permitiendo a los desarrolladores añadir funcionalidades adicionales con facilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declive de jQuery:
&lt;/h2&gt;

&lt;p&gt;Evolución del JavaScript Nativo: Con la llegada de ECMAScript 5 y, posteriormente, ECMAScript 6 (ES6), muchas de las funcionalidades que jQuery proporcionaba se integraron directamente en el lenguaje.&lt;br&gt;
Nuevos Frameworks y Bibliotecas: Frameworks como Angular, React y Vue ofrecieron soluciones más completas y modernas para la creación de aplicaciones web, reduciendo la necesidad de jQuery.&lt;br&gt;
Mejora de los Navegadores: Los navegadores modernizaron sus API, reduciendo las inconsistencias y, por ende, la necesidad de una biblioteca como jQuery para gestionar estas diferencias.&lt;br&gt;
La Situación Actual de React&lt;br&gt;
React, lanzado por Facebook en 2013, se ha convertido en una de las bibliotecas más populares para la construcción de interfaces de usuario, gracias a varias características clave:&lt;/p&gt;

&lt;p&gt;Componentización: React introdujo el concepto de componentes reutilizables, facilitando la gestión de interfaces complejas.&lt;br&gt;
Virtual DOM: React utiliza un DOM virtual para minimizar las operaciones costosas en el DOM real, mejorando el rendimiento.&lt;/p&gt;

&lt;p&gt;Ecosistema y Herramientas: React cuenta con un ecosistema robusto, incluyendo herramientas como Redux para la gestión del estado, y Next.js para el renderizado del lado del servidor.&lt;br&gt;
Adopción y Soporte Empresarial: Grandes empresas han adoptado React, lo que garantiza su soporte continuo y evolución.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Podría React Volverse Obsoleto?
&lt;/h2&gt;

&lt;p&gt;Aunque React goza de una popularidad y uso extensivo en la actualidad, no es invulnerable a los cambios y avances tecnológicos. Aquí algunos factores que podrían influir en su futuro:&lt;/p&gt;

&lt;h2&gt;
  
  
  Emergencia de Nuevas Tecnologías:
&lt;/h2&gt;

&lt;p&gt;Tecnologías más recientes podrían surgir con paradigmas de desarrollo más eficientes. Por ejemplo, Svelte es un framework que compila el código a JavaScript puro, eliminando la necesidad de un virtual DOM.&lt;br&gt;
Evolución del Lenguaje y Estándares Web:&lt;/p&gt;

&lt;p&gt;Si el lenguaje JavaScript y los estándares web continúan evolucionando, podrían integrar de forma nativa muchas de las funcionalidades que actualmente proporcionan bibliotecas como React. Esto podría hacer que los desarrolladores prefieran soluciones nativas más ligeras.&lt;br&gt;
Competencia de Otros Frameworks:&lt;/p&gt;

&lt;p&gt;Frameworks competidores como Vue.js y Angular siguen evolucionando y ofreciendo características únicas que podrían atraer a los desarrolladores. También, frameworks como Solid.js y Qwik, que promueven un rendimiento y eficiencia superiores, podrían ganar terreno.&lt;br&gt;
Saturación del Ecosistema:&lt;/p&gt;

&lt;p&gt;La complejidad creciente del ecosistema de React, con la proliferación de librerías y herramientas adicionales, podría desanimar a los nuevos desarrolladores y conducirlos a buscar alternativas más simples.&lt;/p&gt;

&lt;p&gt;Conclusión&lt;/p&gt;

&lt;p&gt;En resumen, mientras que es difícil predecir con certeza el futuro de cualquier tecnología, la trayectoria de jQuery ofrece lecciones valiosas. React, con su fuerte adopción y apoyo comunitario, está bien posicionado para permanecer relevante en el futuro cercano. Sin embargo, la continua evolución del desarrollo web significa que siempre habrá nuevas tecnologías y paradigmas que podrían desplazar a las herramientas actuales. La clave para la longevidad de React residirá en su capacidad para adaptarse e innovar frente a estos cambios constantes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why are algorithms called algorithms?</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Sun, 26 May 2024 06:39:09 +0000</pubDate>
      <link>https://dev.to/gfouz/why-are-algorithms-called-algorithms-1292</link>
      <guid>https://dev.to/gfouz/why-are-algorithms-called-algorithms-1292</guid>
      <description>&lt;p&gt;The origin of the word dates back more than a thousand years ago. And the invention of the concept is attributed to a Persian polymath and scientist considered “the grandfather of computing.”&lt;/p&gt;

&lt;p&gt;Algorithms have become an integral part of our lives. From social media apps to Netflix, they are programs that learn our preferences and prioritize the content we are shown. Google Maps and artificial intelligence are nothing without them. But where does the word come from?&lt;/p&gt;

&lt;p&gt;More than 1,000 years before the internet and smartphone apps, Persian scientist and polymath Muhammad ibn Mūsā al-Khwārizmī invented the concept of an algorithm. In fact, the word itself comes from the Latinized version of his name, algorithmi. And, as you might suspect, it is also related to algebra.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lost in time
&lt;/h2&gt;

&lt;p&gt;Al-Khwārizmī lived between 780 and 850, during the Islamic Golden Age. He is considered the “father of algebra” and, for some, the “grandfather of computing.” However, few details are known about his life. Many of his original works in Arabic have been lost to time. He is believed to have been born in the Khorasmian region, south of the Aral Sea, in modern-day Uzbekistan. He lived during the Abbasid Caliphate, a time of notable scientific progress in the Islamic Empire.&lt;/p&gt;

&lt;p&gt;We know that he made important contributions to mathematics, geography, astronomy and trigonometry. He corrected Ptolemy 's classic cartography book , Geography , to make the world map more accurate. He also made calculations to track the movement of the Sun, Moon, and planets. In addition, he wrote about trigonometric functions and created the first table of tangents.&lt;/p&gt;

&lt;p&gt;For all his qualities, Al-Khwārizmī served as a scholar in the House of Wisdom (Bayt al-Hikmah) in Baghdad. In this intellectual center, scholars translated knowledge from around the world into Arabic and synthesized it to achieve significant advances in various disciplines.&lt;/p&gt;

&lt;p&gt;A devoted mathematician&lt;br&gt;
Al-Khwārizmī was a religious man. His scientific writings began with dedications to Allah and the Prophet Muhammad. And one of the main projects they undertook at the House of Wisdom was to develop algebra. Mathematics was, in general, a field deeply related to Islam .&lt;/p&gt;

&lt;p&gt;Around 830, the Caliph Al-Mamun encouraged Al-Khwārizmī to write a treatise on algebra, Al-Jabr (or Compendium of Calculus by Reintegration and Comparison ), which would become his most important work.&lt;/p&gt;

&lt;p&gt;By now, algebra had been around for hundreds of years, but Al-Khwārizmī was the first to write a definitive book on it. It was intended to be a practical teaching tool and its Latin translation was the basis of algebra manuals in European universities until the 16th century.&lt;/p&gt;

&lt;h2&gt;
  
  
  Father of algebra
&lt;/h2&gt;

&lt;p&gt;In the first part of the book, he introduces the concepts and rules of this subject, as well as the methods for calculating the volumes and areas of figures. In the second, he poses real-life problems and elaborates solutions, such as inheritance cases, the division of land, and calculations for trade.&lt;/p&gt;

&lt;p&gt;Al-Khwārizmī did not use modern mathematical notation with numbers and symbols. Instead, he wrote in simple prose and used geometric diagrams: Four roots are equal to twenty, so one root is equal to five, and the square formed from it is twenty-five, or half the root is equal to ten.&lt;/p&gt;

&lt;p&gt;In modern notation we would write it like this: 4x = 20, x = 5, x2 = 25, x / 2 = 10&lt;/p&gt;

&lt;h2&gt;
  
  
  Grandfather of computing
&lt;/h2&gt;

&lt;p&gt;Al-Khwārizmī's mathematical writings introduced the Hindu-Arabic numerals to Western mathematicians: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0. These symbols are important to the history of computing because they use the number zero and a base ten decimal system, the number system on which modern computer technology is based.&lt;/p&gt;

&lt;p&gt;Furthermore, Al-Khwārizmī's art of calculating mathematical problems laid the foundation for the concept of algorithm. He provided the first detailed explanations of using decimal notation to perform the four basic operations (addition, subtraction, multiplication, division) and calculating fractions.&lt;/p&gt;

&lt;p&gt;It was a more efficient calculation method than the abacus. To solve a mathematical equation, you systematically went through a sequence of steps until you found the answer. This is the underlying concept of an algorithm.&lt;/p&gt;

&lt;p&gt;Algorithm, a medieval Latin term named after Al-Khwārizmī, refers to the rules for performing arithmetic operations using the Hindu-Arabic number system. Translated into Latin, Al-Khwārizmī's book on Hindu numbers was titled Algorithmi de Numero Indorum .&lt;/p&gt;

&lt;p&gt;At the beginning of the 20th century, the word acquired its current definition and use: “Ordered and finite set of operations that allows finding the solution to a problem.” So the next time we use any digital technology – from social media to the online bank account to the Spotify app – we already know that none of this would be possible without the pioneering work of an ancient Persian polymath.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Introducción a Pydantic para Principiantes.</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Thu, 23 May 2024 18:05:22 +0000</pubDate>
      <link>https://dev.to/gfouz/introduccion-a-pydantic-para-principiantes-b6l</link>
      <guid>https://dev.to/gfouz/introduccion-a-pydantic-para-principiantes-b6l</guid>
      <description>&lt;p&gt;Pydantic es una poderosa biblioteca en Python diseñada para la validación y gestión de datos. Es especialmente útil cuando trabajas con datos que necesitan ser validados y transformados, como datos de entrada de API o formularios. Aquí te explico cómo empezar con Pydantic de manera sencilla.&lt;/p&gt;

&lt;p&gt;¿Qué es Pydantic?&lt;br&gt;
Pydantic permite definir modelos de datos utilizando anotaciones de tipo, y automáticamente valida y transforma los datos según estas anotaciones. Esto significa que puedes asegurarte de que tus datos tienen el formato correcto antes de usarlos en tu aplicación.&lt;/p&gt;

&lt;p&gt;Instalación:&lt;br&gt;
Primero, necesitas instalar Pydantic. Puedes hacerlo usando pip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pydantic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creación de un Modelo o Esquema:&lt;br&gt;
Un modelo en Pydantic es una clase que hereda de BaseModel. Definimos los atributos de esta clase con sus tipos, y Pydantic se encarga del resto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="n"&gt;signup_ts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;span class="n"&gt;friends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, User es un modelo con cuatro atributos:&lt;/p&gt;

&lt;p&gt;id: un entero obligatorio.&lt;br&gt;
name: una cadena de texto obligatoria.&lt;br&gt;
signup_ts: una marca de tiempo opcional.&lt;br&gt;
friends: una lista de enteros, que por defecto es una lista vacía.&lt;/p&gt;

&lt;p&gt;Validación de Datos:&lt;br&gt;
Una vez definido el modelo, podemos crear instancias del mismo y Pydantic validará automáticamente los datos proporcionados.&lt;/p&gt;

&lt;p&gt;Una vez definido el modelo, podemos crear instancias del mismo y Pydantic validará automáticamente los datos proporcionados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signup_ts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;friends&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si los datos no son válidos, Pydantic generará un error.&lt;/p&gt;

&lt;p&gt;Transformación de Datos:&lt;br&gt;
Pydantic también puede transformar los datos según las anotaciones de tipo. Por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;123&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, Pydantic convertirá el id de cadena de texto a entero automáticamente.&lt;/p&gt;

&lt;p&gt;Configuración Avanzada&lt;br&gt;
Pydantic ofrece muchas opciones avanzadas, como alias para nombres de campos, validaciones personalizadas, y uso con JSON.&lt;/p&gt;

&lt;p&gt;Alias&lt;br&gt;
Podemos usar alias para los campos, lo que es útil cuando los nombres de los datos de entrada no coinciden con los de nuestro modelo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integración con JSON&lt;br&gt;
Pydantic facilita trabajar con JSON, permitiendo la exportación e importación de modelos a/desde JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;user_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;user_from_json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_from_json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conclusión&lt;br&gt;
Pydantic es una herramienta poderosa para la validación y transformación de datos en Python. Facilita el trabajo con datos estructurados y ayuda a asegurar que tus datos sean correctos y consistentes. ¡Empieza a usar Pydantic en tus proyectos y simplifica la gestión de datos en tus aplicaciones!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Type hints are a powerful feature in Python</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Mon, 20 May 2024 12:08:48 +0000</pubDate>
      <link>https://dev.to/gfouz/type-hints-are-a-powerful-feature-in-python-ii0</link>
      <guid>https://dev.to/gfouz/type-hints-are-a-powerful-feature-in-python-ii0</guid>
      <description>&lt;p&gt;Type hints are a powerful feature in Python that improve code readability, facilitate error detection, and enhance tooling support. Introduced in PEP 484, type hints allow developers to specify the expected types of variables, function parameters, and return values. While Python remains dynamically typed, these annotations provide significant benefits in terms of code quality and maintainability.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore what type hints are, why you should use them, and how to effectively integrate them into your Python projects.&lt;/p&gt;

&lt;p&gt;What are Type Hints?&lt;br&gt;
Type hints are annotations that specify the types of variables, function parameters, and return values in Python code. They do not enforce type checking at runtime but are used by static type checkers, IDEs, and other tools to provide better code analysis and assistance.&lt;/p&gt;

&lt;p&gt;Here’s a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.75&lt;/span&gt;
&lt;span class="n"&gt;is_student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this snippet, the function greet expects a string parameter and returns a string. Additionally, we define variables with explicit types: age, height, and is_student.&lt;/p&gt;

&lt;p&gt;Why Use Type Hints?&lt;br&gt;
Improved Code Readability: Type hints make the code self-documenting by clearly indicating the expected types, making it easier to understand and maintain.&lt;br&gt;
Early Error Detection: Static type checkers like mypy, pyright, and pylint can catch type-related errors before runtime, reducing the likelihood of bugs.&lt;br&gt;
Better IDE Support: Modern IDEs use type hints for autocompletion, refactoring, and error checking, which significantly enhances the development experience.&lt;br&gt;
Enhanced Documentation: Type hints act as an implicit form of documentation, providing insights into the function’s behavior and expected inputs/outputs.&lt;br&gt;
Using Type Hints with Collections&lt;br&gt;
Python’s typing module provides several generic types for annotating collections. Here are some common examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Tuple&lt;/span&gt;

&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Charlie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;coordinates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;40.7128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;74.0060&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Advanced Type Hinting&lt;br&gt;
Type hints can also handle more complex scenarios such as functions with multiple arguments, optional values, and custom types.&lt;/p&gt;

&lt;p&gt;Multiple Argument Types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Union&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional Values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom Types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NewType&lt;/span&gt;

&lt;span class="n"&gt;UserId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NewType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;UserId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Static Type Checking Tools&lt;br&gt;
To fully leverage the power of type hints, integrating static type checkers into your development workflow is essential. Here are some popular tools:&lt;/p&gt;

&lt;p&gt;mypy: A static type checker for Python that checks type annotations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install mypy
mypy script.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;pyright: A fast type checker by Microsoft, often used with Visual Studio Code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g pyright
pyright script.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;pylint: A code analysis tool that also supports type checking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pylint
pylint script.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Best Practices for Using Type Hints&lt;/p&gt;

&lt;p&gt;Be Consistent: Use type hints consistently throughout your codebase to maintain readability and reliability.&lt;br&gt;
Start Small: If you're new to type hints, start by annotating new functions and gradually add annotations to existing code.&lt;br&gt;
Leverage Tooling: Use static type checkers and IDE support to catch errors early and improve code quality.&lt;br&gt;
Annotate External APIs: Always use type hints for public APIs to provide clear expectations for other developers using your code.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Type hints in Python are an invaluable tool for improving code clarity, reducing errors, and enhancing the development experience. By incorporating type hints into your projects, you can create more maintainable, readable, and robust code. Start using type hints today and see the difference they can make in your Python development workflow.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What a fascinating and new python framework!</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Mon, 20 May 2024 04:44:45 +0000</pubDate>
      <link>https://dev.to/gfouz/what-a-fascinating-python-framework-9a1</link>
      <guid>https://dev.to/gfouz/what-a-fascinating-python-framework-9a1</guid>
      <description>&lt;p&gt;The URL &lt;a href="https://django-ninja.dev/"&gt;https://django-ninja.dev/&lt;/a&gt; is the official website of Django-Ninja, a Python web framework for building APIs with Django and Python 3.6+ type hints.&lt;/p&gt;

&lt;p&gt;This post is based on the official website of Django Ninja:&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;p&gt;Easy: Designed to be easy to use and intuitive.&lt;/p&gt;

&lt;p&gt;FAST execution: Very high performance thanks to &lt;a href="https://pydantic-docs.helpmanual.io/"&gt;Pydantic&lt;/a&gt; and async support.&lt;/p&gt;

&lt;p&gt;Fast to code: Type hints and automatic docs lets you focus only on business logic.&lt;/p&gt;

&lt;p&gt;Standards-based: Based on the open standards for APIs: OpenAPI (previously known as&lt;br&gt;
Swagger) and JSON Schema.&lt;/p&gt;

&lt;p&gt;Django friendly: (obviously) has good integration with the Django core and ORM.&lt;/p&gt;

&lt;p&gt;Production ready: Used by multiple companies on live projects (If you use Django Ninja and&lt;br&gt;
would like to publish your feedback, please email &lt;a href="mailto:ppr.vitaly@gmail.com"&gt;ppr.vitaly@gmail.com&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Other key features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://django-ninja.dev/guides/async-support/"&gt;Async support&lt;/a&gt; :Django-Ninja integrates&lt;br&gt;
acync operations, allowing your application to handle multiple requests concurrently. This results in improved performance, scalability, and responsiveness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Django compatibility: Django-Ninja is built on top of Django and inherits many of its features, such as an&lt;br&gt;
ORM, template engine, and authentication system. This means you can leverage the existing knowledge&lt;br&gt;
and ecosystem of Django.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Micro-architecture: Django-Ninja adopts a micro-architecture approach, which means that your&lt;br&gt;
application is broken down into smaller, independent components (services). This leads to more&lt;br&gt;
maintainable, scalable, and flexible code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type-safe APIs: Django-Ninja uses type-safe APIs, which ensures that your code is more robust and easier&lt;br&gt;
to maintain. You can define your API endpoints with specific types, making it easier to catch errors and&lt;br&gt;
improve code quality.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Improved performance: With asyncio support, your application can handle multiple requests concurrently,&lt;br&gt;
reducing the load on your server and improving response times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better scalability: By using async/await syntax, you can write asynchronous code that's more efficient&lt;br&gt;
and easier to maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easier development: Django-Ninja's micro-architecture approach makes it easier to develop and maintain&lt;br&gt;
your application, with smaller, more focused components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Type-safe APIs: The type-safe API ensures that your code is more robust and easier to maintain.&lt;br&gt;
Who should use Django-Ninja?&lt;/p&gt;

&lt;p&gt;Django-Ninja is suitable for developers who:&lt;/p&gt;

&lt;p&gt;Already have experience with Django or Python web development.&lt;/p&gt;

&lt;p&gt;Are looking for a more modern and efficient alternative to traditional Python web frameworks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;More about Type-safe APIs!&lt;/p&gt;

&lt;p&gt;Type-safe APIs are a crucial aspect of Django-Ninja, and they're essential for building robust, maintainable,&lt;br&gt;
and scalable applications. In this section, I'll dive deeper into what type-safe APIs are and how they benefit&lt;br&gt;
your development process.&lt;/p&gt;

&lt;p&gt;What are Type-Safe APIs?&lt;/p&gt;

&lt;p&gt;Type-safe APIs are a way to define the structure of your API endpoints, including the types of data they&lt;br&gt;
expect and return. In other words, you can specify the types of data that will be sent or received at each&lt;br&gt;
endpoint, ensuring that your code is more robust and easier to maintain.&lt;br&gt;
In Django-Ninja, type-safe APIs are achieved through the use of Python's type hinting system, which allows&lt;br&gt;
you to specify the expected types of function parameters and return values. This enables static type&lt;br&gt;
checking, which can help catch errors early in the development process.&lt;/p&gt;

&lt;p&gt;Benefits of Type-Safe APIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Improved Code Quality: Type-safe APIs ensure that your code is more robust and easier to maintain. By
specifying the expected types of data, you can catch errors early in the development process, reducing
the risk of bugs and crashes.&lt;/li&gt;
&lt;li&gt;Better Error Handling: With type-safe APIs, you can handle errors more effectively. When an error occurs,
you can pinpoint the exact location and type of error, making it easier to debug and fix issues.&lt;/li&gt;
&lt;li&gt;Faster Development: Type-safe APIs enable faster development by providing a clear understanding of the
expected data structures and formats. This reduces the time spent on debugging and troubleshooting.&lt;/li&gt;
&lt;li&gt;Easier Collaboration: When working with a team, type-safe APIs make it easier to collaborate and share
code. Everyone can quickly understand the expected data structures and formats, reducing
misunderstandings and errors.&lt;/li&gt;
&lt;li&gt;Improved Documentation: Type-safe APIs provide a clear and concise documentation of your API
endpoints. This makes it easier for developers to understand how to use your API, reducing the need for
additional documentation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How do Type-Safe APIs work in Django-Ninja?&lt;/p&gt;

&lt;p&gt;In Django-Ninja, you can define type-safe APIs using Python's type hinting system. You can specify the&lt;br&gt;
expected types of function parameters and return values.&lt;br&gt;
For example:&lt;/p&gt;

&lt;p&gt;Retrieving Single object &lt;br&gt;
Suppose we defined a model Employee.&lt;br&gt;
Now to get employee we will define a schema that will describe what our responses will look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;birthdate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Defining response schemas are not really required, but when you do define it you will get results validation,&lt;br&gt;
documentation and automatic ORM objects to JSON conversions.&lt;/p&gt;

&lt;p&gt;We will use this schema as the response type for our GET employee view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees/{employee_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we simply returned an employee ORM object, without a need to convert it to a dict.&lt;br&gt;
The response schema does automatic result validation and conversion to JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees/{employee_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List of objects&lt;br&gt;
To output a list of employees, we can reuse the same EmployeeOut schema. We will just set the&lt;br&gt;
response schema to a List of EmployeeOut .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_employees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another cool trick - notice we just returned a Django ORM queryset:&lt;br&gt;
It automatically gets evaluated, validated and converted to a JSON list!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_employees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, you declare the types of parameters, body, etc. once only, as function parameters.&lt;br&gt;
You do that with standard modern Python types.&lt;/p&gt;

&lt;p&gt;You don't have to learn a new syntax, the methods or classes of a specific library, etc.&lt;br&gt;
Just standard Python 3.6+.&lt;br&gt;
For example, for an int :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, for a more complex Item model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and with that single declaration you get:&lt;/p&gt;

&lt;p&gt;Editor support, including:&lt;br&gt;
Completion&lt;br&gt;
Type checks&lt;br&gt;
Validation of data:&lt;br&gt;
Automatic and clear errors when the data is invalid&lt;br&gt;
Validation, even for deeply nested JSON objects&lt;/p&gt;

&lt;p&gt;Conversion of input data coming from the network, to Python data and types, and reading from:&lt;br&gt;
JSON&lt;br&gt;
Path parameters&lt;br&gt;
Query parameters&lt;br&gt;
Cookies&lt;br&gt;
Headers&lt;br&gt;
Forms&lt;br&gt;
Files&lt;br&gt;
Automatic, interactive API documentation&lt;/p&gt;

&lt;p&gt;What's new in Django Ninja 1.0&lt;/p&gt;

&lt;p&gt;Support for Pydantic2&lt;br&gt;
Pydantic version 2 is re-written in Rust and includes a lot of improvements and features like:&lt;br&gt;
Safer types.&lt;br&gt;
Better extensibility.&lt;br&gt;
Better performance&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
Django-Ninja is an exciting project that brings together the best of simplicity,&lt;br&gt;
robustness ,power and flexibility. If you're interested in building high-&lt;br&gt;
performance web applications with real-time updates or concurrent processing, Django-Ninja is definitely&lt;br&gt;
worth exploring.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What a fascinating python framework!</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Mon, 20 May 2024 04:44:26 +0000</pubDate>
      <link>https://dev.to/gfouz/what-a-fascinating-python-framework-io0</link>
      <guid>https://dev.to/gfouz/what-a-fascinating-python-framework-io0</guid>
      <description>&lt;p&gt;The URL &lt;a href="https://django-ninja.dev/"&gt;https://django-ninja.dev/&lt;/a&gt; is the official website of Django-Ninja, a Python web framework for building APIs with Django and Python 3.6+ type hints.&lt;/p&gt;

&lt;p&gt;This post is based on the official website of Django Ninja:&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;p&gt;Easy: Designed to be easy to use and intuitive.&lt;/p&gt;

&lt;p&gt;FAST execution: Very high performance thanks to &lt;a href="https://pydantic-docs.helpmanual.io/"&gt;Pydantic&lt;/a&gt; and async support.&lt;/p&gt;

&lt;p&gt;Fast to code: Type hints and automatic docs lets you focus only on business logic.&lt;/p&gt;

&lt;p&gt;Standards-based: Based on the open standards for APIs: OpenAPI (previously known as&lt;br&gt;
Swagger) and JSON Schema.&lt;/p&gt;

&lt;p&gt;Django friendly: (obviously) has good integration with the Django core and ORM.&lt;/p&gt;

&lt;p&gt;Production ready: Used by multiple companies on live projects (If you use Django Ninja and&lt;br&gt;
would like to publish your feedback, please email &lt;a href="mailto:ppr.vitaly@gmail.com"&gt;ppr.vitaly@gmail.com&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Other key features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://django-ninja.dev/guides/async-support/"&gt;Async support&lt;/a&gt; :Django-Ninja integrates&lt;br&gt;
acync operations, allowing your application to handle multiple requests concurrently. This results in improved performance, scalability, and responsiveness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Django compatibility: Django-Ninja is built on top of Django and inherits many of its features, such as an&lt;br&gt;
ORM, template engine, and authentication system. This means you can leverage the existing knowledge&lt;br&gt;
and ecosystem of Django.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Micro-architecture: Django-Ninja adopts a micro-architecture approach, which means that your&lt;br&gt;
application is broken down into smaller, independent components (services). This leads to more&lt;br&gt;
maintainable, scalable, and flexible code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type-safe APIs: Django-Ninja uses type-safe APIs, which ensures that your code is more robust and easier&lt;br&gt;
to maintain. You can define your API endpoints with specific types, making it easier to catch errors and&lt;br&gt;
improve code quality.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Improved performance: With asyncio support, your application can handle multiple requests concurrently,&lt;br&gt;
reducing the load on your server and improving response times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better scalability: By using async/await syntax, you can write asynchronous code that's more efficient&lt;br&gt;
and easier to maintain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easier development: Django-Ninja's micro-architecture approach makes it easier to develop and maintain&lt;br&gt;
your application, with smaller, more focused components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Type-safe APIs: The type-safe API ensures that your code is more robust and easier to maintain.&lt;br&gt;
Who should use Django-Ninja?&lt;/p&gt;

&lt;p&gt;Django-Ninja is suitable for developers who:&lt;/p&gt;

&lt;p&gt;Already have experience with Django or Python web development.&lt;/p&gt;

&lt;p&gt;Are looking for a more modern and efficient alternative to traditional Python web frameworks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;More about Type-safe APIs!&lt;/p&gt;

&lt;p&gt;Type-safe APIs are a crucial aspect of Django-Ninja, and they're essential for building robust, maintainable,&lt;br&gt;
and scalable applications. In this section, I'll dive deeper into what type-safe APIs are and how they benefit&lt;br&gt;
your development process.&lt;/p&gt;

&lt;p&gt;What are Type-Safe APIs?&lt;/p&gt;

&lt;p&gt;Type-safe APIs are a way to define the structure of your API endpoints, including the types of data they&lt;br&gt;
expect and return. In other words, you can specify the types of data that will be sent or received at each&lt;br&gt;
endpoint, ensuring that your code is more robust and easier to maintain.&lt;br&gt;
In Django-Ninja, type-safe APIs are achieved through the use of Python's type hinting system, which allows&lt;br&gt;
you to specify the expected types of function parameters and return values. This enables static type&lt;br&gt;
checking, which can help catch errors early in the development process.&lt;/p&gt;

&lt;p&gt;Benefits of Type-Safe APIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Improved Code Quality: Type-safe APIs ensure that your code is more robust and easier to maintain. By
specifying the expected types of data, you can catch errors early in the development process, reducing
the risk of bugs and crashes.&lt;/li&gt;
&lt;li&gt;Better Error Handling: With type-safe APIs, you can handle errors more effectively. When an error occurs,
you can pinpoint the exact location and type of error, making it easier to debug and fix issues.&lt;/li&gt;
&lt;li&gt;Faster Development: Type-safe APIs enable faster development by providing a clear understanding of the
expected data structures and formats. This reduces the time spent on debugging and troubleshooting.&lt;/li&gt;
&lt;li&gt;Easier Collaboration: When working with a team, type-safe APIs make it easier to collaborate and share
code. Everyone can quickly understand the expected data structures and formats, reducing
misunderstandings and errors.&lt;/li&gt;
&lt;li&gt;Improved Documentation: Type-safe APIs provide a clear and concise documentation of your API
endpoints. This makes it easier for developers to understand how to use your API, reducing the need for
additional documentation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How do Type-Safe APIs work in Django-Ninja?&lt;/p&gt;

&lt;p&gt;In Django-Ninja, you can define type-safe APIs using Python's type hinting system. You can specify the&lt;br&gt;
expected types of function parameters and return values.&lt;br&gt;
For example:&lt;/p&gt;

&lt;p&gt;Retrieving Single object &lt;br&gt;
Suppose we defined a model Employee.&lt;br&gt;
Now to get employee we will define a schema that will describe what our responses will look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;department_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;birthdate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Defining response schemas are not really required, but when you do define it you will get results validation,&lt;br&gt;
documentation and automatic ORM objects to JSON conversions.&lt;/p&gt;

&lt;p&gt;We will use this schema as the response type for our GET employee view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees/{employee_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we simply returned an employee ORM object, without a need to convert it to a dict.&lt;br&gt;
The response schema does automatic result validation and conversion to JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees/{employee_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List of objects&lt;br&gt;
To output a list of employees, we can reuse the same EmployeeOut schema. We will just set the&lt;br&gt;
response schema to a List of EmployeeOut .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_employees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another cool trick - notice we just returned a Django ORM queryset:&lt;br&gt;
It automatically gets evaluated, validated and converted to a JSON list!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="nd"&gt;@api.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/employees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EmployeeOut&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_employees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
       &lt;span class="n"&gt;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;qs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, you declare the types of parameters, body, etc. once only, as function parameters.&lt;br&gt;
You do that with standard modern Python types.&lt;/p&gt;

&lt;p&gt;You don't have to learn a new syntax, the methods or classes of a specific library, etc.&lt;br&gt;
Just standard Python 3.6+.&lt;br&gt;
For example, for an int :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or, for a more complex Item model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and with that single declaration you get:&lt;/p&gt;

&lt;p&gt;Editor support, including:&lt;br&gt;
Completion&lt;br&gt;
Type checks&lt;br&gt;
Validation of data:&lt;br&gt;
Automatic and clear errors when the data is invalid&lt;br&gt;
Validation, even for deeply nested JSON objects&lt;/p&gt;

&lt;p&gt;Conversion of input data coming from the network, to Python data and types, and reading from:&lt;br&gt;
JSON&lt;br&gt;
Path parameters&lt;br&gt;
Query parameters&lt;br&gt;
Cookies&lt;br&gt;
Headers&lt;br&gt;
Forms&lt;br&gt;
Files&lt;br&gt;
Automatic, interactive API documentation&lt;/p&gt;

&lt;p&gt;What's new in Django Ninja 1.0&lt;/p&gt;

&lt;p&gt;Support for Pydantic2&lt;br&gt;
Pydantic version 2 is re-written in Rust and includes a lot of improvements and features like:&lt;br&gt;
Safer types.&lt;br&gt;
Better extensibility.&lt;br&gt;
Better performance&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
Django-Ninja is an exciting project that brings together the best of simplicity,&lt;br&gt;
robustness ,power and flexibility. If you're interested in building high-&lt;br&gt;
performance web applications with real-time updates or concurrent processing, Django-Ninja is definitely&lt;br&gt;
worth exploring.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Relaciones many to many: conceptos y fundamentos.</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Fri, 17 May 2024 03:16:39 +0000</pubDate>
      <link>https://dev.to/gfouz/relaciones-many-to-many-conceptos-y-fundamentos-5884</link>
      <guid>https://dev.to/gfouz/relaciones-many-to-many-conceptos-y-fundamentos-5884</guid>
      <description>&lt;p&gt;Al crear una aplicación con Django u otro framework, a menudo te encuentras con situaciones en las que necesitas establecer relaciones entre modelos. Un tipo común de relación es la relación de muchos a muchos&lt;br&gt;
(M2M).&lt;br&gt;
En este artículo, exploraremos qué son las relaciones M2M, cuándo usarlas y cómo implementarlas en&lt;br&gt;
Django y Django Ninja.&lt;/p&gt;

&lt;p&gt;¿Qué son las relaciones de muchos a muchos?&lt;/p&gt;

&lt;p&gt;En una relación tradicional uno a uno (1:1) o uno a muchos (1:N), cada registro de una tabla corresponde&lt;br&gt;
exactamente a un registro de otra tabla. Por el contrario, una relación de muchos a muchos (M2M) es un&lt;br&gt;
tipo de relación en la que un registro de una tabla se puede asociar con varios registros de otra tabla y&lt;br&gt;
viceversa. A esto se le suele denominar tabla de "puente" o "unión".&lt;/p&gt;

&lt;p&gt;Cuándo utilizar relaciones de muchos a muchos&lt;/p&gt;

&lt;p&gt;Hay varios escenarios en los que es posible que desee utilizar relaciones M:N&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Etiquetado o categorización : cuando tienes un modelo que se puede asociar con múltiples categorías o&lt;br&gt;
etiquetas, como una publicación de blog que se puede etiquetar con múltiples temas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Roles o permisos de usuario : cuando necesita asignar múltiples roles o permisos a un usuario, como&lt;br&gt;
administrador, moderador o colaborador.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asociaciones de muchos a muchos : cuando necesita establecer relaciones entre múltiples modelos,&lt;br&gt;
como un libro que se puede asociar con múltiples autores y múltiples géneros.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cómo implementar relaciones de muchos a muchos utilizando Django?&lt;/p&gt;

&lt;p&gt;Para implementar una relación M:N en Django, necesitarás crear dos modelos y luego usar la clase&lt;br&gt;
ManyToManyField en el archivo de modelos.&lt;/p&gt;

&lt;p&gt;He aquí un ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# models.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.utils.text&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;slugify&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# return self.name
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SlugField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;image_src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SlugField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now_add&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto_now&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ManyToManyField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Split the title into words
&lt;/span&gt;        &lt;span class="n"&gt;first_two_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# Select the first two words
&lt;/span&gt;        &lt;span class="n"&gt;formatted_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_two_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Replace spaces with
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;slugify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image_src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;slugify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatted_title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este caso, Django creará automáticamente una tabla intermedia que se encargará de almacenar las&lt;br&gt;
relaciones entre los usuarios y sus roles. Podemos entonces acceder a las relaciones utilizando el&lt;br&gt;
método categories en el modelo Post.&lt;/p&gt;

&lt;p&gt;Al utilizar la clase ManyToManyField evita la creación de una tabla intermedia adicional, lo que puede mejorar el rendimiento y la escalabilidad.&lt;/p&gt;

&lt;p&gt;Proporciona una forma más fácil y concisa de definir relaciones muchos a muchos.&lt;br&gt;
Permite acceder a las relaciones utilizando métodos naturales o (built-in) en los modelos.&lt;/p&gt;

&lt;p&gt;En resumen, la elección entre utilizar el mecanismo automático de Django o crear una tabla intermedia&lt;br&gt;
manualmente depende del proyecto y las necesidades específicas. Es importante considerar las ventajas y&lt;br&gt;
desventajas de cada opción antes de tomar una decisión.&lt;br&gt;
Siempre que sea posible es más simple utilizar ManyToManyField en lugar de una tabla intermedia cuando se trata de una relación muchos a muchos en Django.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/3.2/ref/models/fields/#manytomanyfield"&gt;https://docs.djangoproject.com/en/3.2/ref/models/fields/#manytomanyfield&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ejemplo de creación de una tabla intermedia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# models.py
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IntermediaryModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForeignKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_delete&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;is_released&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BooleanField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;#...
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya con los modelos creados podemos utilizarlos para crear registros&lt;br&gt;
en nuestra base de datos e implementar una API en este caso con Django&lt;br&gt;
Ninja veamos un ejemplo:&lt;/p&gt;

&lt;p&gt;Primero creamos los esquemas en un archivo que convencionalmente se llama&lt;br&gt;
schemas.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ninja&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ModelSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Schema&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;posts.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ErrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelSchema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# exclude = ["last_login", "user_permissions"]
&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CategorySchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelSchema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelSchema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserSchema&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CategorySchema&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;slug&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;categories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CategoryFullSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostFullSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;image_src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserSchema&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CategoryFullSchema&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostUpdateSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostCreateSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;author_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego de crear los esquemas entonces creamos otro archivo que suele llamarse&lt;br&gt;
api.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ninja&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NinjaAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ninja.responses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_object_or_404&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;posts.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ninja.security&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpBearer&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;posts.schemas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PostUpdateSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserSchema&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;posts.schemas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PostFullSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PostCreateSchema&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;posts.schemas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CategorySchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CategoryFullSchema&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;posts.schemas&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ErrorMessage&lt;/span&gt;


&lt;span class="nd"&gt;@router.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/get/single/post/{post_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PostFullSchema&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HttpError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not found!.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nd"&gt;@router.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/postlist/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;PostFullSchema&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_all_posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="nd"&gt;@router.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/create/post-category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PostFullSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ErrorMessage&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_post_and_category&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PostCreateSchema&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title already exists&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HttpError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title already exists&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;category_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;category_name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;category_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;category_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Puede tomar como punto de partida el ejemplo anterior y ajustarlo&lt;br&gt;
a sus necesidades.&lt;/p&gt;

&lt;p&gt;En el mundo de la programación, las relaciones entre objetos son fundamentales para representar y&lt;br&gt;
manipular datos. En este sentido, las relaciones muchos a muchos (M:N) son especialmente útiles cuando se&lt;br&gt;
necesitan representar conexiones entre objetos que pueden tener múltiples asociaciones&lt;/p&gt;

&lt;p&gt;En conclusión, las relaciones de muchos a muchos son una herramienta poderosa que permite establecer relaciones complejas entre modelos. Si comprende cuándo utilizarlos y cómo implementarlos, podrá crear aplicaciones más sólidas y escalables.&lt;/p&gt;

&lt;p&gt;Espero que este artículo haya sido útil. Si tiene alguna pregunta o desea obtener más información sobre este tema, ¡no dude en preguntar!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Portfolio built with Typescript and Python</title>
      <dc:creator>Giovani Fouz</dc:creator>
      <pubDate>Thu, 09 May 2024 10:27:40 +0000</pubDate>
      <link>https://dev.to/gfouz/portfolio-built-with-typescript-and-python-e1h</link>
      <guid>https://dev.to/gfouz/portfolio-built-with-typescript-and-python-e1h</guid>
      <description>&lt;p&gt;Combining a portfolio and blog together in a Django project can be a great way to showcase your work as well as share your thoughts and experiences.&lt;/p&gt;

&lt;p&gt;In building a portfolio and blog platform with React, Tailwind CSS, React Hook Form, Tanstack Query, Zod, React Router DOM, Zustand, and Django Ninja, you are tapping into a powerful combination of front-end and back-end technologies that offer a wide range of technical features and capabilities.&lt;/p&gt;

&lt;p&gt;React is a highly popular JavaScript library for building user interfaces, offering a component-based approach that promotes reusability, efficiency, and ease of development. With React's declarative syntax and virtual DOM, you can create dynamic and interactive UI components for your portfolio and blog.&lt;/p&gt;

&lt;p&gt;Tailwind CSS is a utility-first CSS framework that streamlines the design process by providing a set of pre-built utility classes for styling elements. With Tailwind CSS, you can easily customize styling, maintain consistency across your project, and speed up development without writing custom CSS styles.&lt;/p&gt;

&lt;p&gt;React Hook Form is a lightweight and performant form validation library for React applications. By leveraging React Hook Form, you can easily manage form state, handle form validation, and enhance user input experience in your portfolio and blog platform.&lt;/p&gt;

&lt;p&gt;Tanstack Query is a powerful data fetching library for React applications that simplifies remote data fetching, caching, and synchronization with a robust query syntax. By integrating Tanstack Query, you can efficiently manage data fetching from the back-end and optimize the performance of your portfolio and blog.&lt;/p&gt;

&lt;p&gt;Zod is a TypeScript-first schema validation library that provides a robust way to validate data structures and ensure data integrity in your application. By using Zod, you can define data schemas, validate input data, and handle error states with ease in your portfolio and blog platform.&lt;/p&gt;

&lt;p&gt;React Router DOM is a routing library for React applications that enables declarative routing and navigation within your web application. With React Router DOM, you can define and manage routes, create nested navigation structures, and ensure seamless navigation between different pages in your portfolio and blog.&lt;/p&gt;

&lt;p&gt;Zustand is a simple and flexible state management library for React applications that offers a minimalistic approach to managing global state. By leveraging Zustand, you can efficiently manage and share state across React components, handle complex data flows, and improve the performance of your portfolio and blog platform.&lt;/p&gt;

&lt;p&gt;Django Ninja is a fast API framework for building web APIs with Django, providing a lightweight and intuitive approach to creating RESTful APIs. With Django Ninja as your back-end technology, you can effortlessly define API endpoints, handle data requests and responses, authenticate users, and interact with databases to power the dynamic content of your portfolio and blog platform. Integrated documentation generation in Django Ninja simplifies API documentation and client integration tasks&lt;/p&gt;

&lt;p&gt;By harnessing the technical features of these front-end and back-end technologies, you can create a seamless and efficient portfolio and blog platform that delights users with responsive design, interactive functionality, secure data handling, and a smooth browsing experience.&lt;/p&gt;

&lt;p&gt;I invite you to explore my GitHub repository to delve into the source code of the projects mentioned above and witness the full scope and intricacies of these innovative solutions. Dive into the code, explore the functionalities, and see firsthand how these technologies work together to create remarkable applications. Your visit to my GitHub repository would be greatly appreciated, and I look forward to sharing the details of these projects with you. Join me on GitHub to discover the good behind the code!&lt;/p&gt;

&lt;p&gt;PORTFOLIO AND BLOG SOURCE CODE:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gfouz/react-ninja"&gt;https://github.com/gfouz/react-ninja&lt;/a&gt; .git&lt;br&gt;
&lt;a href="https://github.com/gfouz/ninja-server"&gt;https://github.com/gfouz/ninja-server&lt;/a&gt; .git&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
