Wagtail es un CMS que se integra con Django y nos permite crear páginas de forma visual. No obstante, hay situaciones donde debemos crear páginas de forma automática como, por ejemplo, cuando tenemos que importar un gran número de páginas desde un JSON o es necesario dar herramientas a los diseñadores web con datos falsos lo más diversos posible.
Para ello, podemos crear un script de Python que se conecte con los modelos de Django y cree las páginas que necesitemos.
Contexto
Partiremos de 2 paginas clásicas de un blog común. BlogListPage
será página que contiene las entradas de blog y BlogIndexPage
que es la página individual de cada entrada, que a su vez es hija de BlogListPage
.
class BlogListPage(Page):
subpage_types = ["public.BlogPage"]
class BlogIndexPage(Page):
summary = models.TextField(_("Summary"), default="")
body = RichTextField()
date = models.DateField(_("Post date"))
cover = models.ForeignKey(
"wagtailimages.Image",
blank=False,
on_delete=models.PROTECT,
related_name="blog_cover",
)
is_highlighted = models.BooleanField(_("Is highlighted?"), default=False)
content_panels = Page.content_panels + [
FieldPanel("summary"),
FieldPanel("body"),
FieldPanel("date"),
FieldPanel("is_highlighted"),
FieldPanel("cover"),
]
parent_page_types = ["public.BlogListPage"]
subpage_types = []
Como puedes observar, en BlogIndexPage
tenemos nuevos campos con tipos de lo más diversos.
summary
es un campo de texto.body
es un campo de texto enriquecido (salida en HTML).date
es una fecha.cover
es una imagen.is_highlighted
es un booleano.
Cada uno de ellos lo trataremos de forma individual.
Solución
1. Subir imagen
Nota: Ignora este paso si no necesitas incluir una imagen.
El campo cover
es una imagen, por ello previamente habrá que subirla o seleccionar una que ya exista en la base de datos.
Si es el segundo caso, reutilizar una existente, podemos buscarla con el modelo Image
de Wagtail.
from wagtail.images.models import Image
my_new_cover = Image.objects.filter(title="Mi imagen").first()
En caso de necesitar subir una nueva imagen, se complica pero no es imposible.
En el siguiente ejemplo, subiremos una imagen aleatoria descargada directamente desde internet.
from wagtail.images.models import Image
import requests
from django.core.files import File
from tempfile import NamedTemporaryFile
from random import randint
url_random_imagen = (
f"https://cdn.jsdelivr.net/gh/tanrax/place-image-random/images/{randint(1, 1000)}.jpg"
)
r = requests.get(url_random_imagen)
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(r.content)
img_temp.flush()
my_new_image = File(img_temp)
my_new_cover = Image.objects.create(title="Mi nueva imagen", file=my_new_image)
En ambos casos, ya tenemos la imagen en la variable my_new_cover
. Podemos pasar a crear la página.
2. Crear página
Primero debemos importar nuestros modelos. En este caso, BlogListPage
y BlogIndexPage
están en app.public.models
. En tu situación puede que estén en otro sitio.
from app.public.models import BlogListPage, BlogIndexPage
Aprovecharemos para importar datetime
con el objetivo de crear una fecha.
from datetime import datetime
Un requisito para crear una página de Wagtail es instanciar la página padre. En este caso, BlogListPage
.
parent_page = BlogListPage.objects.first().specific
Se necesita el método specific
para obtener la instancia de la página y no el modelo.
Ahora ya podemos crear la página. En este caso, BlogIndexPage
.
new_item = BlogIndexPage()
new_item.title = "Mi titulo"
new_item.body = "<p>Mi contenido</p>"
new_item.date = datetime.now()
new_item.summary = "Soy un resumen"
new_item.cover = my_new_cover
new_item.is_highlighted = False
Por último, debemos añadir la página a la página padre y listo.
parent_page.add_child(instance=new_item)
La página ya está creada. Si necesitas crear más, puedes repetir el proceso todas las veces que necesites.
Extra: Crear páginas masivas con contenido falso o de prueba
Si necesitas crear un gran número de páginas, puedes utilizar la librería Faker.
from faker import Faker
fake = Faker()
Con ella, puedes crear contenido falso para rellenar los campos de las páginas.
En el siguiente ejemplo se crean 10 páginas con contenido falso.
from faker import Faker
from app.public.models import BlogListPage, BlogIndexPage
from datetime import datetime
from wagtail.images.models import Image
import requests
from django.core.files import File
from tempfile import NamedTemporaryFile
from random import randint
# Variables
fake = Faker()
parent_page = BlogListPage.objects.first().specific
# Functions
def get_random_image():
url_random_imagen = (
f"https://cdn.jsdelivr.net/gh/tanrax/place-image-random/images/{randint(1, 1000)}.jpg"
)
r = requests.get(url_random_imagen)
img_temp = NamedTemporaryFile(delete=True)
img_temp.write(r.content)
img_temp.flush()
return File(img_temp)
def create_image():
my_new_image = get_random_image()
return Image.objects.create(title=fake.sentence(), file=my_new_image)
def create_page():
new_item = BlogIndexPage()
new_item.title = fake.sentence()
new_item.body = "\n".join([f"<p>{fake.sentence()}</p>" for _ in range(randint(10, 100))])
new_item.date = fake.date_time_this_year()
new_item.summary = fake.sentence()
new_item.cover = create_image()
new_item.is_highlighted = fake.boolean()
parent_page.add_child(instance=new_item)
for i in range(10):
create_page()
Si necesitas crear más, puedes cambiar el range(10)
por el número de páginas que necesites.
{{ comments.length }} comentarios