Header Ads Widget

Ticker

6/recent/ticker-posts

Creación de una API de CMS sin cabeza con Flask


 Siga esta guía para crear un CMS sin cabeza en solo diez pasos.

Supongamos que desea iniciar un blog o mostrar sus productos y servicios en un sitio web. Una opción es construir todo desde cero usando HTML, CSS y JavaScript. Esto requeriría la creación de bases de datos, un inicio de sesión de administrador e interfaces para que pueda iniciar sesión y actualizar la información. Como esto requiere mucho esfuerzo, probablemente debería utilizar un sistema de gestión de contenido (CMS) probado si no está familiarizado con la programación. Un CMS proporciona todas las herramientas necesarias para administrar contenido y aplicar diferentes diseños a un sitio web listo para usar.

Hay muchos CMS diferentes disponibles , como WordPress, Wix, Contentful o Squarespace, que se pueden usar para generar sitios web y aplicaciones web. Un CMS proporciona interfaces de edición visual, plantillas, código personalizado y otras capacidades de administración de contenido, todo desde un solo entorno. WordPress, una de las opciones más poderosas, cuenta con muchos complementos para extender el comportamiento e introducir poderosas capacidades de comercio electrónico.

Entonces, ahora surge la siguiente pregunta: ¿qué es un CMS sin cabeza ?

¿Qué es un CMS sin cabeza?

Entonces, hemos estado usando CMS durante aproximadamente 20 años. Sin embargo, el mundo ha cambiado mucho. La era móvil actual ha experimentado un gran crecimiento en fronteras novedosas, como IoT, bots, asistencia digital y realidad virtual. Sin embargo, el CMS tradicional no se creó para estas plataformas de vanguardia.

Hoy en día, el contenido debe mostrarse en una variedad de dispositivos en diferentes formatos. Dado que el CMS tradicional no se desarrolló para este propósito, necesitamos un nuevo tipo de sistema de administración de contenido independiente del cliente. Aquí es donde entra en juego el CMS sin cabeza.

Un CMS sin cabeza se centra únicamente en el proceso de administración del contenido. No controla el aspecto de la presentación de la interfaz. En cambio, un CMS sin cabeza utiliza una API para proporcionar contenido a los canales finales. De esta manera, un CMS sin cabeza se separa del cliente (el "cabezal") y, por lo tanto, no tiene cabeza. El uso de API para separar preocupaciones significa que su contenido se puede entregar a cualquier plataforma; podría ser un sitio web de Angular, una aplicación móvil o incluso un reloj inteligente.

Ventajas de Headless CMS

  • Es más seguro en comparación con el CMS tradicional.
  • También es de menor tamaño
  • Más rápido que el CMS convencional
  • Te permite elegir cualquier idioma para el desarrollo de frontend.
  • Te permite publicar tu contenido en diferentes plataformas.

Contras de Headless CMS

  • Tienes que administrar dos partes al mismo tiempo: el backend y el frontend
  • Necesitará una infraestructura completamente diferente para mantener la interfaz
  • Puede ser más costoso de mantener que un CMS tradicional.

Algunos CMS sin cabeza populares

  • Directus
  • Prismico
  • Kentico Kontent
  • Bloomreach
  • Magnolia

Ahora que entendemos qué es un CM sin cabeza, aprendamos a crear uno. En este tutorial, crearemos un CMS sin cabeza usando Flask y MySQL.

Prerrequisitos

  • Pitón
  • MySQL
  • Matraz
  • Editor de código como VS Code
  • MySQL
  • SQLalchemy

Paso - 1: la configuración

Abra su terminal y cree una nueva carpeta usando el comando mkdirEstamos usando cmscomo nombre de carpeta:

mkdir cms

Ahora abre la carpeta:

cd cms
virtualenv .
pipenv install flask flask-sqlalchemy flask-cors

Ahora debemos crear diferentes archivos y carpetas dentro de la carpeta raíz. Por el bien de este tutorial, cree esta estructura de cinco carpetas y un archivo:

  • Blog
  • Acceso
  • Etiqueta
  • blog_tags
  • Usuario
  • __init__.py

Ahora cree también algunos archivos de Python. La estructura de carpetas final tiene que ser así:

  • Blog
    - blog_model.py
    - blog_routes.py
  • Iniciar sesión
    - login_route.py
  • Etiqueta
    - tag_model.py
  • blog_tags
    - blog_tag_table.py
  • Usuario
    - user_model.py

Una vez que haya creado la estructura del proyecto, ahora instale FlaskvirtualenvYa hemos explicado cómo configurar el matraz en un artículo anterior. Puede consultarlo aquí y luego continuar con los siguientes pasos.

Instalemos flask-sqlalchemyEn su terminal, pegue el siguiente comando:

python3 -m pip install flask-sqlalchemy

¿Qué es exactamente flask-sqlalchemyBueno, es una extensión de Flask que agrega soporte sqlalchemyy simplifica muchas tareas de MySQL. Utiliza Object Relational Mapping (ORM), lo que facilita la ejecución de consultas sin escribir las declaraciones SQL sin procesar.

Inicializando

Una vez instaladas todas las dependencias, es hora de escribir código. Entonces, abra cms/__init__.pyen su editor de código y pegue el siguiente código:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

db = SQLAlchemy()

def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
CORS(app)

db.init_app(app)

return app

Explicación:

Aquí hemos creado una función llamada create_app(), que básicamente inicializa nuestra aplicación y base de datos al mismo tiempo, que podemos usar en cualquier parte del código.

Paso 2: configuración de la base de datos

En este paso, crearemos tablas para nuestro CMS sin cabeza. Estas tablas almacenarán todos los datos que publicaremos a través de nuestro CMS. Vamos a empezar con la tabla blog que tendrá columnas: idtitletextdate_of_publishimagetagsSi lo desea, puede agregar algunas columnas más si es necesario, pero por ahora, en aras de la simplicidad, solo estamos creando las columnas básicas que se encuentran en la mayoría de los CMS.

Ahora abra Blog/blog_model.pyy pegue el siguiente código:

from cms import db
from datetime import datetime
from cms.blog_tags.blog_tag_table import tag_blog

tags=db.relationship('Tag',secondary=tag_blog,backref=db.backref('blogs_associated',lazy="dynamic"))

class Blog(db.Model):
id = db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(50),nullable=False)
text=db.Column(db.Text,nullable=False)
image= db.Column(db.String,nullable=False)
date_of_publish = db.Column(db.DateTime, default=datetime.utcnow)

@property
def serialize(self):
return {
'id': self.id,
'title': self.title,
text: self.text,
image: self.image,
date_of_publish: self.date_of_publish,
}

Explicación

Aquí estamos importando diferentes módulos como dbpara conexiones de bases de datos y datetimepara marcas de tiempo. Hemos creado un modelo Blogy hemos definido todos los campos en él. Hay una función llamada serialize(self), que se usa para devolver todos los datos en formato JSON.

Es posible que haya notado que no hemos definido etiquetas aquí, ¿verdad? Esto se debe a que tagses una clave externa que vendrá de una tabla completamente diferente llamada tagsBásicamente, una publicación puede tener muchas etiquetas y una etiqueta se puede asociar con varias publicaciones de blog.

Ahora abra cms/Tag/tag_model.pyy pegue el siguiente código:

from cms import db

class Tag(db.Model):
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(20))
@property
def serialize(self):
return {
'id': self.id,
'name': self.name
}

Explicación

Hemos definido el modelo con columnas idnameya que las etiquetas no requieren más que estas columnas.

Una vez que el modelo está listo, es hora de crear una tabla también, así que abra el archivo cms/blog_tags/blog_tag_table.pyy pegue el siguiente código:

from cms import db

tag_blog = db.Table('tag_blog',
db.Column('tag_id',db.Integer,db.ForeignKey('tag.id'), primary_key=True),
db.Column('blog_id', db.Integer,db.ForeignKey('blog.id'),primary_key=True)
)

Explicación:

Esta tabla contiene la relación entre la tabla de blogs y la tabla de etiquetas con la que tag_idse asigna blog_id.

Paso –3: Agregar planos:

Ahora tenemos que editar el archivo Blog/blog_routes.pyy agregar las siguientes líneas de código:

blogs= Blueprint('blogs',__name__)

Abra cms / __init__.pyy agregue el siguiente código:

from cms.Blog.blog_routes import blogs
app.register_blueprint(blogs)

Explicación:

Estamos agregando planos aquí. Nos ayuda a dividir la aplicación en pequeños componentes que se pueden reutilizar en cualquier lugar. Aquí lo hemos definido blogscomo anteproyecto.

Paso –4: Creación de una ruta para publicar una publicación de blog

Ahora abra su blog_routes.pyy agregue el siguiente código:

from flask import Blueprint,request,jsonify,make_response
from flask_jwt_extended import jwt_required
from cms import db
from cms.Blog.blog_model import Blog
from cms.Tag.tag_model import Tag

blogs= Blueprint('blogs',__name__)
@blogs.route('/add_post',methods=["POST"])
def create_blog():
data = request.get_json()

new_blog=Blog(title=data["title"],content=data["content"],image=data["image"])

for tag in data["tags"]:
current_tag=Tag.query.filter_by(name=tag).first()
if(current_tag):
current_tag.blogs_associated.append(new_blog)
else:
new_tag=Tag(name=tag)
new_tag.blogs_associated.append(new_blog)
db.session.add(new_tag)

db.session.add(new_blog)
db.session.commit()

blog_id = getattr(new_blog, "id")
return jsonify({"id": blog_id})

Explicación:

Hemos creado una ruta /blog_post, que invoca la función que creará create_blog()Esta función se utiliza básicamente para crear una publicación de blog y acepta título, texto, imagen y etiquetas. Estamos ejecutando un ciclo en el que puede aceptar varias etiquetas, y si una etiqueta no existe, creará una nueva etiqueta y la asociará con la publicación del blog.

Paso –5: Creación de una ruta para obtener las publicaciones del blog:

Crearemos dos rutas diferentes para buscar las publicaciones del blog. Una ruta buscará todas las publicaciones del blog, mientras que la otra se utilizará para buscar publicaciones de blog sobre la base de idEsto se puede usar para buscar en las publicaciones del blog cuando un usuario abre la publicación completa del blog. Ahora abra blog_routes.pyy pegue el siguiente código:

@blogs.route('/blogs',methods=["GET"])
def get_all_blogs():
blogs= Blog.query.all()
serialized_data = []
for blog in blogs:
serialized_data.append(blog.serialize)

return jsonify({"all_blogs": serialized_data})

Explicación:

Hemos definido una ruta /blogs, que ejecuta una SELECTconsulta usando el ORM y devuelve un JSON que contiene todas las publicaciones del blog y sus datos bajo la all_blogsclave.

Ahora, para obtener la publicación del blog, idpegue el siguiente código:

@blogs.route('/blog/<int:id>',methods=["GET"])
def get_single_blog(id):
blog = Blog.query.filter_by(id=id).first()
serialized_blog = blog.serialize
serialized_blog["tags"] = []

for tag in blog.tags:
serialized_blog["tags"].append(tag.serialize)

return jsonify({"single_blog": serialized_blog})

Explicación:

Hemos definido otra ruta /blog, que acepta un valor entero y devuelve todos los datos del blog en un JSON bajo la single_blogclave.

Paso –6: Creación de una ruta para eliminar una publicación de blog:

Hasta ahora hemos cubierto cómo crear un blog. Ahora, aquí se explica cómo eliminar una publicación de blog. En blog_routes.py, pegue el siguiente código:

@blogs.route('/delete_post/<int:id>', methods=["DELETE"])
def delete_post(id):
blog = Blog.query.filter_by(id=id).first()
db.session.delete(blog)
db.session.commit()

return jsonify("Blog was deleted"),200

Explicación:

Aquí hemos definido una ruta /delete_post, que acepta el idde la publicación del blog y ejecuta la consulta de eliminación para el blog asociado id.

Paso –7: Creación de una ruta para actualizar una publicación de blog:

Para actualizar una publicación de blog, usaremos el PUTmétodo aquí que tomará un blog idcomo parámetro de entrada. Entonces, blog_routes.pyagregue el siguiente código:

@blogs.route('/update_post/<int:id>', methods=["PUT"])
def update_post(id):
data = request.get_json()
blog=Blog.query.filter_by(id=id).first_or_404()

blog.title = data["title"]
blog.text=data["text"]
blog.image=data["image"]

updated_blog = blog.serialize

db.session.commit()
return jsonify({"blog_id": blog.id})

Explicación:

Hemos agregado una ruta más /update_postes decir , que usa el PUTmétodo y ejecuta una UPDATEconsulta en el blog pasado id.

Paso 8: Agregar usuario administrador y ruta de inicio de sesión:

Ahora hemos definido todas las rutas que pueden realizar operaciones CRUD en la publicación del blog. Pero también tenemos que evitar el acceso no autorizado, ¿verdad? Esto garantizará que ninguna persona no autorizada pueda actualizar o agregar una publicación de blog.

Entonces, primero crearemos un modelo de usuario que se utilizará para almacenar la información del usuario. Entonces, abra el archivo cms/User/user_model.pyy pegue el siguiente código:

from cms import db

class User(db.Model):
id=db.Column(db.Integer,primary_key=True)
email=db.Column(db.String(120),nullable=False)
password=db.Column(db.String(120),nullable=False)

Aquí solo tendremos un usuario administrador, por lo que no necesitamos crear una ruta para eso. Entonces, en su __init__.pyarchivo, pegue el siguiente código:

@click.command(name='add_admin')
@with_appcontext
def add_admin():
admin=User(email="ADMIN EMAIL",password="YOUR PASSWORD STRING")
admin.password = generate_password_hash(admin.password,'sha256',salt_length=12)
db.session.add(admin)
db.session.commit()

app.cli.add_command(add_admin)

Y en la parte superior, agregue el siguiente código:

import click
from flask.cli import with_appcontext
from werkzeug.security import generate_password_hash

Explicación:

Aquí almacenamos el correo electrónico y la contraseña del usuario administrador. Ahora no podemos almacenarlo como texto sin formato, por lo que estamos usando SHA256hash.

Una vez que se realiza la parte anterior, tenemos que crear una ruta para el inicio de sesión de administrador. Entonces, para hacer eso, tenemos que abrir el Login/login_route.pyarchivo y pegar el siguiente código:

from flask import Blueprint,request,jsonify
from cms.User.user_model import User
from flask_jwt_extended import create_access_token
from werkzeug.security import check_password_hash

login=Blueprint('login', __name__)

@login.route('/login', methods=["POST"])
def log_in():
request_data = request.get_json()

user=User.query.filter_by(email=request_data["email"]).first()
if user:
if check_password_hash(user.password,request_data["password"]):
jwt_token=create_access_token(identity=user.email)
return jsonify({"token":jwt_token})
else:
return "Invalid email or password",400

Explicación:

Aquí hemos definido una ruta /login, que llevará correo electrónico y contraseña. Una vez que ambos sean correctos, devolverá un token JWT que puede usar para realizar las siguientes solicitudes.

Paso –9: Implementación de JWT:

Ahora hemos agregado un usuario administrador y la parte de inicio de sesión también está lista. Pero para hacerlo más seguro, implementaremos JWT add_postupdate_postpara evitar el acceso no autorizado. En su terminal, pegue el siguiente código:

pipenv install flask-jwt-extended

Esto instalará JWT, que puede usar para implementar JWT.

Ahora, abra __init__.pyy pegue el siguiente código:

app.config['JWT_SECRET_KEY']=ADD YOUR SECRET STRING HERE
jwt=JWTManager(app)

Ahora abra el archivo Blog_routes.pyy actualice las siguientes rutas:

@blogs.route('/delete_post/<int:id>', methods=["DELETE"])
@jwt_required
def delete_post(id):
blog = Blog.query.filter_by(id=id).first()
db.session.delete(blog)
db.session.commit()

return jsonify("Blog was deleted"),200

Del mismo modo, agregue lo mismo @jwt_requireddebajo de la línea@blogs.route('/add_post',methods=["POST"])

Paso –10: Finalización de la configuración:

Al final, cms/__init__.pydebería verse algo como esto:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
import click
from flask.cli import with_appcontext
from flask_jwt_extended import JWTManager
from werkzeug.security import generate_password_hash

db = SQLAlchemy()

def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdatabase.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
CORS(app)
db.init_app(app)
app.config['JWT_SECRET_KEY']='YOUR_SECRET_KEY'
jwt=JWTManager(app)

from cms.Blog.blog_routes import blogs
app.register_blueprint(blogs)

from cms.User.user_model import User

from cms.Login.login_route import login
app.register_blueprint(login)

from cms.Tag.tag_model import Tag

@click.command(name='create_admin')
@with_appcontext
def create_admin():
admin=User(email="ANY_EMAIL",password="ANY_PASSWORD")
admin.password = generate_password_hash(admin.password,'sha256',salt_length=12)
db.session.add(admin)
db.session.commit()

app.cli.add_command(create_admin)


return app

Una vez que haya terminado con todo, simplemente necesita ejecutar el siguiente comando para que la base de datos funcione. Así que pégalo en tu terminal:

python
from cms import db,create_app
db.create_all(app=create_app())

Esto creará un archivo flaskdatabase.dbque contiene todas las tablas. Ahora, para ejecutar el servidor API, use el comando:

set FLASK_APP=cms/__init__.py
set FLASK_DEBUG=1
set FLASK_ENV=development
flask create_admin
flask run

¡¡¡Y Bingo !!! Estás listo para realizar llamadas a la API para crear publicaciones de blog. Puede clonar código listo para usar de este repositorio .

Ultimas palabras

En este artículo, hemos cubierto mucho terreno, como cómo hacer conexiones SQL, cómo ejecutar consultas SQL usando SQLalchemy, implementación de JWT y más, todo para generar un CMS sin cabeza. Puede decir que este es un tipo de artículo todo en uno, que puede ayudarlo a comenzar a aprender algunos conceptos avanzados en Python-Flask.

Publicar un comentario

0 Comentarios