Publicidad

Como ejecutar consultas RAW en django


Por Alex el 04/02/2024, Comentar el artículo

Comparte este artículo:      




Django utiliza modelos donde se pueden crear entidades y construir consultas a través de los modelos programando con Python peeeero ... también podemos ejecutar consultas SQL en modo raw, es decir, una select .... de toda la vida.


Para realizar esto tienes que crearte un modelo que tendrá dos funciones, una para ejecutar consultas que devuelven datos ExecuteQuery y otra función para ejecutar acciones Execute. Execute también puede ejecutar selects pero solo devuelve un resultado.

Lo primero que has de hacer es crear un proyecto Django o utilizar uno que ya tengas, en el ejemplo lo creo de cero.

Si aun no tienes muy claro como crear proyectos web en Django aquí te dejo un artículo para crear proyectos en django desde cero en Linux.
Crear un proyecto Django desde cero en Linux, voy a utilizar esta base para este artículo.

Una vez creado en la aplicación web creamos dos fichero:
  • baseModel.py, donde creamos las funciones para ejecutar las consultas.
  • filmModel.py, donde pondremos las consultas en modo RAW que pertenecen a la tabla film

El fichero baseModel.py contiene el siguiente código:


from django.db import connection


class BaseModel:
  
  def ExecuteQuery ( sql, params=None):
    cursor = connection.cursor()
    cursor.execute(sql, params if params is not None else [])

    columns = [col[0] for col in cursor.description]

    rows = [ dict(zip(columns, row)) for row in cursor.fetchall() ]

    return [ { 'columns': columns, 
               'rows': rows,
               'total': cursor.rowcount       
            } ]
    

  def Execute ( sql, params=None):
    cursor = connection.cursor()
    cursor.execute(sql, params if params is not None else [])

    try:
      queryset = cursor.fetchone()
      if queryset is not None:
        return [ queryset]
      else:
        return []
    except Exception as e:
      return []



Este fichero tiene dos funciones:
  • ExecuteQuery, devuelve un conjunto de registros, también devuelve el nombre de los campos y el número de registros devueltos.

    Resultado en JSON del método EjecuteQuery


  • Execute, devuelve un único registro en un select o un null en un insert, delete, update si todo va OK.

y en el fichero filmModel.py contiene el siguiente código:


from .baseModel import BaseModel

class FilmModel(BaseModel):

  def GetAllFilms():
    sql = "SELECT film_id, title, release_year, language_id, special_features \
          FROM `film` \
          Order by film_id desc limit 3"
    params = []
    return ( list(BaseModel.ExecuteQuery( sql, params)))
  
  def AddOneFilm():
    # sql = "INSERT INTO `film` (`title`, `description`, `release_year`, `language_id`, `original_language_id`, \
    #        `rental_duration`, `rental_rate`, `length`, `replacement_cost`, `rating`, `special_features`, `last_update`) \
    #         VALUES ('pruebas01', NULL, NULL, '1', NULL, '3', '4.99', NULL, '19.99', 'G', NULL, CURRENT_TIMESTAMP)"
    sql = "INSERT INTO film (title, description, release_year, language_id, original_language_id, rental_duration, rental_rate, length, replacement_cost, rating, special_features, last_update) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, CURRENT_TIMESTAMP)"
    params = ('pruebas01', None, None, '1', None, '3', '4.99', None, '19.99', 'G', None)

    return ( list(BaseModel.Execute( sql, params)))
  
  def DeleteOneFilm():
    sql = "delete from film where film_id = %s"
    params = [1001,]
    return ( list(BaseModel.Execute( sql, params)))


Ahora desde la vista lanzamos estas consultas y recogemos los datos para mostrarlos por pantalla. El fichero views.py queda así:


from django.shortcuts import render
from django.core.serializers import serialize
from django.http import HttpResponse, JsonResponse
from .filmModel import FilmModel


def index( request):

  films = FilmModel.GetAllFilms()

  return JsonResponse( films, safe=False)


def add(request):

  film_add = FilmModel.AddOneFilm()

  return JsonResponse( film_add, safe=False)

def delete(request):

  film_add = FilmModel.DeleteOneFilm()

  return JsonResponse( film_add, safe=False)



Como es un proyecto nuevo para poder probarlo tenemos que configurar varias cosas en el proyecto, el fichero settings,py donde ponemos la configuración de nuestra aplicación en INSTALLED_APPS


INSTALLED_APPS = [
   # other apps
    'webapp'
]


webapp es el nombre de la aplicación web que hemos creado.

En este mismo fichero también configuramos el acceso a la base de datos en DATABASES (es mi configuración docker)


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'sakila',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '172.21.0.2',   
        'PORT': '3306',
    }
}


y también hay que enlazar las URLs que queremos utilizar con nuestra webapp y para esto hay que modificar el fichero urls.py del mismo project_admin y poner lo siguiente:


path('', include('webapp.urls'))


El array de urlpatterns, quedará así:


from django.contrib import admin
from django.urls import path, include

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


Y crea un fichero llamado urls.py en tu webapp. Dentro pondrás las rutas que quieras utilizar. En el ejemplo tendremos dos rutas / para listar los films y add para añadir uno.

Y quedará así:


from django.urls import path
from .views import index, add, delete

urlpatterns = [
    path('', index, name="index"),
    path('add', add, name="add"),
    path('delete', delete, name="delete"),
]


Para poder probarlo arranca el servidor que django incorpora:

python manage.py runserver

Y al poner en el navegador la url http://127.0.0.1:8000 tiene que aparecer en el navegador un json con los registros.

Si ejecutas http://127.0.0.1:8000/add creará un nuevo registro.

Vale, y ahora me dirás y como lo paso a verlo en html, como este JSON se trata en un template, pues muy buena pregunta, ahora vamos a verlo.

Ahora en el fichero views.py mostramos el resultado de las consultas en el navegador como JSON con la instrucción:


return JsonResponse( films, safe=False)


Este código lo comento para que puedas hacer pruebas y en su lugar añadimos el siguiente código:


return render(request, 'index.html', {
    'films': films,
  })


index.html, este archivo se tienen que crear en un directorio llamado templates, y es donde poner el html y los datos del array film que como puedes ver se lo pasamos a la vista.


{% for film in films %}
    {{ film }}
{% endfor %}


Dejo todo el código en el repositorio de git
https://github.com/depruebas/django-queries-raw

Y esto es todo, feliz programming
Saludos
Alex
/

Si te ha gustado el artículo compartelo en:      




Añadir un comentarios:

Nombre:
Email: (no se publica el email)




SIGUENOS EN

ARCHIVO

Publicidad

.