Saltar a contenido

45. Django

45.1 Enlaces de interes

  • Curso webinar
  • https://developer.mozilla.org/es/docs/Learn/Server-side/Django/Introduction
  • https://tutorial.djangogirls.org/es/

45.2 Resetear Base de datos

En ciertas ocasiones aparecen errores relacionados con cambios en el modelo cuando ya se han insertado registros en la base de datos y que dan errores al ejecutar cualquier comando.

En este y otros casos extremos , la solución inmediata es borrar la base de datos junto con otros ficheros relacionados.

PASOS:

Borrar el fichero db-sqlite3 ( se perderán todos los datos, incluido el usuario de administración) En cada app , borrar todos los ficheros del directorio "migrations" excepto el fichero init.py Realizar los cambios en el modelo Ejecutar makemigrations, migrate y createsuperuser

45.3 Django rest framework

Revisar video sobre REST y http https://www.youtube.com/watch?v=OHBHeAPoZ8E y https://www.youtube.com/watch?v=K589vqhuMm8


Documentación para Django Rest API Framework

Vamos a empezar con la Guía Rápida de Inicio

En esda web de swagger podéis encontrar herramientas y documentación sobre REST API

Ejemplo de servidor REST:  petshop swagger

Librerias (paquetes ) para clients REST API:

45.3.1 Ejemplo django restframework y cliente requests

Para el ejemplo de este lunes.

Un recorte de código típico para utilizar cualquier REST API como cliente.

Páginas de ayuda: 


Sólo se necesita el paquete "requests" que sirve para hacer peticiones HTTP, sean o no para rest-api

pip install requests   (cuidado que este activado el entorno virtual con python3, o utilizar : python3 -m pip install requests)  ....

-------------------

El siguiente ejemplo pide todas las canciones y obtiene algunos de sus valores a partir de la representacion json.

Se puede utilizar el interfaz web que desarrollamos esta mañana con django-restframework para comprobar las peticiones y la estructura devuelta al hacer llamadas rest-apii

--------------

from email.policy import default
from pprint import pprint
from unittest import case
import requests
from requests.auth import HTTPBasicAuth

URL_BASE='http://localhost:8000/'
AUTE=HTTPBasicAuth('admin', 'examendam')


respuesta= requests.get(
URL_BASE +'cancion/', auth=AUTE
)
print("La respuesta en formato json :")
pprint( respuesta.json)

print("Ejemplo de obtención de datos : ")

#=======
# La respuesta es una lista de diccionario con dos claves: titulo y fecha
# Lo veis en el serializador y en las páginas web del proyecto
#========
for cancion in respuesta.json():
   print(f"{ cancion['titulo']} : {cancion['fecha']}")



45.4 Dockerizar Django, postgres, guernicon y nginx

Basado en esta web.

45.4.1 Entorno de desarrollo

Creamos un nuevo proyecto Django

$ mkdir django-on-docker && cd django-on-docker
$ mkdir app && cd app
$ python3.9 -m venv env
$ source env/bin/activate
(env)$

(env)$ pip install django==3.2.6
(env)$ django-admin.py startproject hello_django .
(env)$ python manage.py migrate
(env)$ python manage.py runserver

Observar que django-admin tiene tres parámetros: stratproyecto, el nombre y el directorio con "." lo que significa que manage.py esta en ./app

(recordar si no funciona venv: instalar venv)

python3.11 django-4.1.4

Borramos db.sqlite3 puesto que vamos a utilizar postgres

45.4.2 Creamos imagen Docker y Probamos

Creamos una imagen alpine con python3.11 usando

En el directorio app

Dockerfile
# pull official base image
FROM python:3.11-alpine

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY . .
Donde las variables * PYTHONDONTWRITEBYTECODE: Prevents Python from writing pyc files to disc (equivalent to python -B option) * PYTHONUNBUFFERED: Prevents Python from buffering stdout and stderr (equivalent to python -u option)

Y creamos un docker-compose.yml para crear el contenedor

docker-compose.yml
version: '3.8'

services:
  web:
    build: ./app
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - ./app/:/usr/src/app/
    ports:
      - 8001:8000
    env_file:
      - ./.env.dev

En el proyecto Django cambiamos los settings:

SECRET_KEY = os.environ.get("SECRET_KEY")

DEBUG = int(os.environ.get("DEBUG", default=0))

# 'DJANGO_ALLOWED_HOSTS' should be a single string of hosts with a space between each.
# For example: 'DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]'
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS").split(" ")
LANGUAGE_CODE = 'es-es'

TIME_ZONE = 'Europe/Madrid'
Asegurnadose se usar import os

Ahora necesitamos crear el fichero .env.dev con:

DEBUG=1
SECRET_KEY=foo
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
Los directorios quedan así:

.
├── app
│   ├── Dockerfile
│   ├── env
│   ├── hola
│   ├── manage.py
│   ├── requirements.txt
│   └── venv311
└── docker-compose.yml
(docker-compose.yml un nivel sobre app)

45.4.3 Postgres

To configure Postgres, we'll need to add a new service to the docker-compose.yml file, update the Django settings, and install Psycopg2.

Prrimero añadimos un nuevo servicio db to docker-compose.yml:

docker-compose.yml
version: '3.8'

services:
  web:
    build: ./app
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - ./app/:/usr/src/app/
    ports:
      - 8001:8000
    env_file:
      - ./.env.dev
    depends_on:
      - db
  db:
    image: postgres:15.1-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=hola
      - POSTGRES_PASSWORD=holapw
      - POSTGRES_DB=hola_dev

volumes:
  postgres_data:

y nuevas variables de entorno

.env.dev
DEBUG=1
SECRET_KEY=foo
DJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
SQL_ENGINE=django.db.backends.postgresql
SQL_DATABASE=hola_dev
SQL_USER=hola
SQL_PASSWORD=holapw
SQL_HOST=db
SQL_PORT=5432

Y en el proyecto django actualizamos settings

DATABASES = {
    "default": {
        "ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
        "NAME": os.environ.get("SQL_DATABASE", BASE_DIR / "db.sqlite3"),
        "USER": os.environ.get("SQL_USER", "user"),
        "PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
        "HOST": os.environ.get("SQL_HOST", "localhost"),
        "PORT": os.environ.get("SQL_PORT", "5432"),
    }
}

Se configura según las variables de entorno y si no existe como sqlite3.

Update the Dockerfile to install the appropriate packages required for Psycopg2:

Dockerfile
# pull official base image
FROM python:3.11-alpine

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install psycopg2 dependencies
RUN apk update \
    && apk add postgresql-dev gcc python3-dev musl-dev

# install dependencies
RUN pip install --upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# copy project
COPY . .