Mostrando entradas con la etiqueta python manage.py migrate. Mostrar todas las entradas
Mostrando entradas con la etiqueta python manage.py migrate. Mostrar todas las entradas

lunes, 2 de enero de 2023

6.- Django - Bases de Datos.

  ¿Te pierdes entre tantos temas? 📚✨ Descubre todo lo que ofrece este blog en un solo vistazo [👉 Ver índice completo]

Se supone que ya sabes que es una base de datos, tablas, registros etc 

Para ver este tema vamos a simular que creamos una tienda virtual. Empezaremos un nuevo proyecto independiente del que ya teníamos. Tecleamos:

$ django-admin startproject tiendaVirtual

Entramos dentro de la carpeta del nuevo proyecto creado:

$ cd tiendaVirtual

En este tema vamos a trabajar con varias aplicaciones que aunque están relacionadas van a hacer cosas distintas. Empezaremos creando una aplicación a la que llamaremos "gestiónPedidos". Django pude trabajar con diferentes aplicaciones independientes. Podríamos tener una aplicación para "Gestión de Almacén", otra para "Cobros y Pagos", otra para "Clientes" y así sucesivamente. 

En los capítulos anteriores no utilizamos Aplicaciones para nada, pero en la mayoría de los proyectos se requiere modularización  y usar a la vez diferentes aplicaciones.

Creamos la nueva aplicación:

tiendaVirtual$ python manage.py startapp gestionPedidos

Esto ha creado un nuevo directorio en nuestro proyecto:

Nueva aplicación creada

Si entramos en el, podemos ver los siguientes archivos:

archivos creados con la aplicacion


Una vez que hemos creado la primera aplicación, vamos a ver como crear las bases de datos. La clave está en el archivo models.py. Se trata de crear dentro de este archivo una clase por cada tabla que necesites que tenga tu base de datos. Cada clase hereda de models.Model. Lo bueno será que no tenemos que usar ni una sola instrucción de SQL todo esto lo hace por detrás DJANGO. 


models.py: Creación de tablas y campos.

from django.db import models

# Create your models here.

# Las tablas se crean mediante clases.

class Clientes(models.Model):
    # Dentro de la clase se crean los diferentes campos.
    nombre = models.CharField(max_length=30)
    direccion = models.CharField(max_length=50)
    # Email ya valido ya esta creado
    email = models.EmailField()
    telefono = models.CharField(max_length=9)

class Articulos(models.Model):
    nombre = models.CharField(max_length=30)
    categoria = models.CharField(max_length=20)
    precio = models.IntegerField()

class Pedidos(models.Model):
    numero = models.IntegerField
    fecha = models.DateField()
    entregado = models.BooleanField()
Hemos creado tres tablas Clientes, Artículos y Pedidos. 

En la tabla Clientes cada registro tendrá tres campos:
- nombre (campo de texto)
- dirección (campo de texto)
- email (es un tipo de campo ya preparado para aceptar emails válidos)
- teléfono (campo de texto)

En la tabla Artículos registraremos:
- nombre (campo de texto)
- categoría (campo de texto)
- precio (campo numérico)

En la tabla Pedidos registraremos:
- número de pedido (campo numérico)
- fecha (campo de fecha)
- si esta entregado o no (campo boleano)

 En el siguiente enlace puedes ver los diferentes tipos de campos que existen:


METADATOS.

Los metadatos en una tabla es "cualquier cosa que no es un campo o columna", cosas como la forma de ordenación de los registros (ordering), nombres de las tablas en la base de datos (db_table), o nombres que los humanos podamos entender tanto en singular como plural para los campos (verbose_name y verbose_name_plural).

Puedes encontrar una lista de las posibles opciones para la clase Meta en "model option reference" de la documentación de Django.

Vamos a ver algunos ejemplos.

Si cuando hagamos una consulta (query) a la base de datos queremos que los datos se muestren ordenados en base a un determinado campo usaremos la opción "ordering" de la clase Meta. Por ejemplo, si cuando consultemos la tabla "Clientes" queremos que estos se ordenen alfabéticamente podemos usar la clase Meta dentro de la clase Clientes de la siguiente forma:

models.py: Creación de tablas y campos.

from django.db import models

# Create your models here.

# Las tablas se crean mediante clases.

class Clientes(models.Model):
    # Dentro de la clase se crean los diferentes campos.
    nombre = models.CharField(max_length=30)
    direccion = models.CharField(max_length=50)
    # Email ya valido ya esta creado
    email = models.EmailField()
    telefono = models.CharField(max_length=9)
    
    class Meta:
        ordering = ["nombre"]

...
Si en vez de que aparezcan ordenados en orden ascendentes queremos que aparezcan en orden descendente usaremos un menos delante del nombre del campo. 

ordering = ["-nombre"]

También utilizando metadatos podemos crear un índice para la base de datos. Como realizaremos muchas consultas a la base de datos, consultando el número del pedido, vamos a indexar la tabla "Pedidos" en función de este campo. Esto mejorará el rendimiento de las consultas que realicemos ordenando o filtrando los datos por este campo.

models.py: Creación de tablas y campos.

from django.db import models

# Create your models here.

# Las tablas se crean mediante clases.

...

class Pedidos(models.Model):
    numero = models.IntegerField
    fecha = models.DateField()
    entregado = models.BooleanField()

    class Meta:
        indexes = [models.Index(fields=["numero"]),]



Ya tenemos la primera aplicación y modelo (3 tablas) y unos metadatos. El siguiente paso es decirle a nuestro proyecto de DJANGO que hay una aplicación nueva, porque hasta ahora no lo sabe. Hay que regístralo en "settings.py" dentro de la carpeta "tiendaVirtual". 

Ahí hay una sección llamada "INSTALLED_APPS"
que por defecto tiene todas las aplicaciones de Django existentes por el solo hecho de crearlo.  Ahí añadiremos el nombre de la aplicación:

tiendaVirtual/settings.py: Registro de aplicaciones.

...
ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'gestionPedidos',
]

MIDDLEWARE = [
...
Guardamos y a modo de prueba podemos teclear el siguiente comando para ver si todo esta bien. La siguiente salida es que el proyecto esta correctamente registrado:

/DJANGO/tiendaVirtual$ python manage.py check gestionPedidos
System check identified no issues (0 silenced).
Para crear la base de datos, con las tres tablas:

python manage.py makemigrations nombre_aplicación
Realizará la migraciones solo de esta aplicación o también puedes usarla sin el nombre de la aplicación con lo que comprobará todas las aplicaciones y realizará las migraciones en todas las tablas del proyecto.


/tiendaVirtual$ python manage.py makemigrations gestionPedidos
Migrations for 'gestionPedidos':
  gestionPedidos/migrations/0001_initial.py
    - Create model Articulos
    - Create model Clientes
    - Create model Pedidos
0001 - número de migración.

Pero ¡ojo! porque esto crea la base de datos y le dice a Django lo que debería tener la base de datos en su interior pero si miramos dentro con cualquiera de los programas que existen para ello, veremos que esta vacía.

Si tienes curiosidad de como se creará la tabla con instrucciones del código SQL puedes usar la siguiente instrucción aunque no es obligatoria, solo si tienes curiosidad de ver el código, que posteriormente se aplicará al realizar la migración.

/tiendaVirtual$ python manage.py sqlmigrate gestionPedidos 0001
BEGIN;
--
-- Create model Articulos
--
CREATE TABLE "gestionPedidos_articulos" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "nombre" varchar(30) NOT NULL, "categoria" varchar(20) NOT NULL, "precio" integer NOT NULL);
--
-- Create model Clientes
--
CREATE TABLE "gestionPedidos_clientes" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "nombre" varchar(30) NOT NULL, "direccion" varchar(50) NOT NULL, "email" varchar(254) NOT NULL, "telefono" varchar(9) NOT NULL);
--
-- Create model Pedidos
--
CREATE TABLE "gestionPedidos_pedidos" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "fecha" date NOT NULL, "entregado" bool NOT NULL);
COMMIT;

 Ahora, como último paso le decimos que las aplique, es decir ejecutamos la migración, esto si es obligatorio porque sino no se aplicarán los cambios:

/tiendaVirtual$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, gestionPedidos, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying gestionPedidos.0001_initial... OK
  Applying sessions.0001_initial... OK
Si en el directorio del proyecto, buscas y abres el archivo db.sqlite3 (con DB Browser por ejemplo), verás que tiene 14 tablas. La mayor parte las utiliza Django para su uso pero también están las nuestras:

tablas creadas en el archivo de la base de datos


Si te fijas Django añade por defecto un campo id que se añade como clave primaria, en caso de que tu no lo hagas, que también podrías.


¿Cómo crear, actualizar y borrar registros de la base de datos?


Para comenzar vamos a hacerlo desde la consola, aunque el objetivo final será hacerlo desde formularios que creemos en la página web. Pero hasta que no veamos como hacer formularios en Django, tendremos que hacerlo desde la consola.

Para ello abriremos el "shell" de Django dentro de nuestra aplicación (tiendaVirtual) de la siguiente forma:

~/Cursos/DJANGO/tiendaVirtual$ python manage.py shell
Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

Lo primero que vamos a hacer es importar el modelo con el que vamos a trabajar. Por ejemplo vamos a crear un registro de la tabla Artículos. Comenzamos importando el modelo.


~/Cursos/DJANGO/tiendaVirtual$ python manage.py shell
Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from gestionPedidos.models import Articulos
Vamos a insertar un primer Articulo dentro de la tabla artículos. Creamos una variable que la podemos llamar como queramos, yo la llamaré "juego" y luego asignaremos cada uno de los campos, teniendo en cuenta si la propiedad es de tipo texto, entero etc. Por ejemplo insertaremos en nuestra tienda virtual un primer videojuego:

"Doom", "Acción", 3 €

~/Cursos/DJANGO/tiendaVirtual$ python manage.py shell
Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from gestionPedidos.models import Articulos
>>> juego=Articulos(nombre="Doom", categoria="Acción", precio= 3)
Para que esto tenga efecto y se cree el registro utilizamos el método .save() sobre la variable creada.

~/Cursos/DJANGO/tiendaVirtual$ python manage.py shell
Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from gestionPedidos.models import Articulos
>>> juego=Articulos(nombre="Doom", categoria="Acción", precio= 3)
>>> juego.save()

y ya tenemos el registro creado.

imagen de registro creado en la base de datos


Para practicar vamos a insertar un segundo artículo.

>>> juego2=Articulos(nombre="Need for Speed", categoria="Velocidad", precio=50)
>>> juego2.save()
>>> 
Nuevo registro creado en la base de datos

Existe otra forma de insertar un registro con una sola instrucción que es usando el método "objects.create". 

El administrador predeterminado para cada modelo es objects. Este administrador recupera todos los objetos en la base de datos, aunque también podemos crear gestores de modelos personalizados (aunque no los vamos a ver en este curso).

Creemos un tercer articulo para verlo.

>>> juego3=Articulos.objects.create(nombre="Animal Crossing",categoria="Simulación", precio=45)
tercer articulo creado con una sola instrucción


Actualizar un registro.

Imaginemos que queremos modificar el precio del juego "Need for Speed" para subirlo a 60 Euros. Para realizar esta tarea, como use la variable "juego2" para crear el objeto, modificamos el precio de la siguiente forma:

>>> juego2.precio=60
>>> juego2.save()
>>>
y si vamos a la base de datos y actualizamos ya estaría modificado el precio.

Borrar registro.

Por ejemplo vamos a borrar el juego "Animal Crossing" que yo cree usando la variable "juego3". Podemos usar de nuevo esta variable u otra nueva (da igual el nombre de la variable) por ejemplo "borrar". Le especificamos el modelo (Articulos) y usamos objets.get para especificar el criterio. Podemos especificar el id, el nombre etc del registro. Yo usare el id del registro que en mi caso es el 3. Y una vez tenemos el registro seleccionado lo borramos usando el método "delete()"

>>> borrar = Articulos.objects.get(id=3)
>>> borrar.delete()
(1, {'gestionPedidos.Articulos': 1})
>>> 

resultado de borrar el registro numero 3


Para realizar una consulta que nos muestre todos los registros que tenemos almacenados en la tabla podemos usar le método .all()


>>> lista_articulos = Articulos.objects.all()
>>> lista_articulos
<QuerySet [<Articulos: Articulos object (1)>, <Articulos: Articulos object (2)>]>
>>> 
Si tienes curiosidad de ver la instrucción SQL que genera lo anterior solo tienes que ejecutar lo siguiente para verla:

>>> lista_articulos.query.__str__()
'SELECT "gestionPedidos_articulos"."id", "gestionPedidos_articulos"."nombre", "gestionPedidos_articulos"."categoria", "gestionPedidos_articulos"."precio" FROM "gestionPedidos_articulos"'
>>> 

Próximo Post - 7. Bases de Datos. Postgresql en local.

sábado, 19 de noviembre de 2022

1.- Django - Instalación y Primera Página.


 ¿Te pierdes entre tantos temas? 📚✨ Descubre todo lo que ofrece este blog en un solo vistazo [👉 Ver índice completo]

¿Que es Django?

De forma muy resumida podemos decir que es un "framework" de Python para crear entornos web. 


1) Instalación.

Se puede instalar en local o también, que suele ser lo normal, en un entorno virtual. Todos los ejemplos que siguen están realizados en un entorno virtual.

Para instalarlo vamos a su página y buscamos la sección de descargas. Ni que decir tiene que tienes que tener Python instalado en tu ordenador para poder ejecutar Django. Personalmente como estoy en Linux, lo voy a instalar con: 

$ sudo pip3 install Django

o también,  a fecha en la que he escrito esta entrada, la última versión con:

pip install Django==4.1.3

Para ver si esta correctamente instalado, entramos en la consola de Python y tecleamos:

(miEntorno) chema@lenovo:~/Cursos/DJANGO$ python
Python 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.VERSION
(4, 1, 3, 'final', 0)


2) Creación de un proyecto.

Un Proyecto se organiza como un grupo de aplicaciones individuales que trabajan juntas para que el proyecto funcione como un todo.

Empezaremos creando una carpeta donde guardar el proyecto (DJANGO en mi caso). Entramos en ella y desde el terminal, podemos hacerlo de dos formas:

a) $ django-admin startproject Nombre_Proyecto

(como nombre de proyecto escogí Proyecto1)

Se creará una carpeta con el nombre que le hayamos puesto al proyecto y si entramos en ella veremos el siguiente esquema de directorio:

Proyecto1



o

b) $ django-admin startproject Nombre_Proyecto .

Importante el punto final. La diferencia está en que de esta forma se nos crea el proyecto con forma de directorio para que sea más fácil desplegarlo. Quedaría así:

Proyecto1


Cuestión de gustos o funcionalidad el elegir una y otra. (el directorio miEntorno es el entorno virtual que he creado, no se instala con Django).

El archivo manage.py es muy importante porque nos permite interactuar con los proyectos Django de varias formas. Si vamos a la consulta y ejecutamos:

$ ./manage.py help o bien python manage.py help

Nos ofrece una salida con todas las instrucciones y comandos que puede ejecutar. (entre ellos el parámetro startproject ya visto)

(miEntorno) chema@lenovo:~/Cursos/DJANGO$ ./manage.py help

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[contenttypes]
    remove_stale_contenttypes

[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    optimizemigration
    sendtestemail
    shell
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp
    startproject
    test
    testserver

[sessions]
    clearsessions

[staticfiles]
    collectstatic
    findstatic
    runserver


Dentro de la carpeta del proyecto creada tenemos otros archivos que son:

__init__.py 

Es un archivo necesario para que Python trate el directorio del proyecto - Proyecto1 en el ejemplo - como un paquete.

settings.py 

Contiene, como te puedes imaginar por el nombre, todas las configuraciones de nuestro proyecto de Django.

urls.py

Es donde se almacenan las urls o direcciones de nuestro proyecto.

wsgi.py

Es el servidor web que vamos a utilizat en el proyecto de Django.


3) Creación de la Base de Datos del Proyecto.


Para que el proyecto se ponga en funcionamiento tenemos que crear una base de datos. Por defecto Django utiliza Sqlite3, aunque como veremos más tarde también soporta oficialmente PostgreSql, MySql o Oracle. Con desarrollos de terceros también es posible utilizar Sql server, Sap Sql, db2, Firebird etc.

Para empezar vamos a crear la que se utiliza por defecto Sqlite3, con el siguiente comando:

$ python manage.py migrate

>>> (miEntorno) chema@lenovo:~/Cursos/DJANGO$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK


Dentro de la carpeta Principal se habrá generado un archivo db.sqlite3.

base de datos sqlite3


El proyecto ya está listo para funcionar. Para ver que todo va bien tenemos que ejecutar un servidor web y usar el navegador para ver la página de bienvenida de Django. El servidor web que viene con Django es útil para probar nuestro proyecto pero NO para ponerlo en producción, sirve para ver si nuestros proyectos funcionan y se ven.


$ python manage.py runserver


>>> (miEntorno) chema@lenovo:~/Cursos/DJANGO$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
November 09, 2022 - 17:13:08
Django version 4.1.3, using settings 'proyecto1.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Ahora si abres el navegador web que utilices y vas a la dirección:


http://127.0.0.1:8000/

o

http://localhost:8000/

podrás ver, si esta todo instalado correctamente la página de bienvenida de Django:

Pagina de instalación correcta de Django

Vamos a personalizar algunos elementos de Django como son la hora local y el idioma. Por defecto la aplicación utiliza por defecto el idioma ingles y como hora local UTC (Coordinated Universal Time) que en verano es dos horas menos que la nuestra. (si estás en España)

Para cambiarlo busca el archivo settings.py y busca los siguientes valores:

...
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True
...

Puedes usar el idioma y tu hora local, pero si quieres usar el Castellano y poner la hora de España cambia los siguientes valores:

LANGUAGE_CODE = 'es-es'

TIME_ZONE = 'Europe/Madrid'

4) Creación de una página web sencilla "Hola Mundo".

Lo primero que tenemos que hacer es crear un archivo nuevo que va a almacenar las diferentes vistas que vayamos almacenando. Este archivo, por convención, se suele llamar views.py. Estará dentro de la carpeta que contiene los demás, donde está el __init__.py.

Lo primero que tenemos que hacer es importar:

views.py

# Importar el módulo
from django.http import HttpResponse

# El nombre de la primera vista será Saludo
def saludo(request):
    return HttpResponse("Hola Mundo")

A cada función que creemos dentro de views.py se le denomina vista.

Ahora debemos decirle a Python cual es la Url que debemos introducir en el navegador para que nos de esta vista.

Esto se lo decimos en el archivo urls.py. En el mismo, al abrirlo, ya vienen las instrucciones de como construirla. Tiene que tener la siguiente estructura:

path("nombreurl/", nombre_de_la_vista)

nombreurl/ -> podemos poner el que nosotros queramos, pero por coherencia debería coincidir con el nombre de la función. (Hay que poner la barra al final).

nombre de la vista -> el mismo que pusimos en el archivo views.py

y como la función está en un archivo diferente al que nos encontramos hay que importarla:

from nombre_proyecto.views import nombre_de_la_vista

nombre_proyecto será el nombre de la carpeta que lo contiene:

En mi ejemplo: (en negrita está lo que se ha añadido de nuevo al archivo)

from django.contrib import admin
from django.urls import path
from Proyecto1.views import saludo

urlpatterns = [
    path('admin/', admin.site.urls),
    path('saludo/', saludo),
]

Si ejecutamos de nuevo el servidor de Django:

$ python manage.py runserver

y vamos a la siguiente Url: localhost:8000/saludo/

debemos ver lo siguiente:

hola mundo en Django

Próximo Post. 2.- Contenido dinámico e introducción de parámetros en url.