Reputation: 1
I'm wanting to convert an existing snippet model into a page model, along with migrating all existing data from the snippet model. Is there a way to do this without having to manually convert the data/ create a script to generate pages from the existing models?
I've updated the model, ran the migrations etc. and can create new pages for this type in the wagtail UI, but the existing data hasn't been migrated over and there's no new page models for it. References/links to the old snippet models are still intact, but there's nowhere to view/edit the model as it no longer appears as a snippet and hasn't been migrated over to a page.
Upvotes: 0
Views: 113
Reputation: 1258
Have you looked at routable pages in Wagtail?
You can keep your data in the snippets and call up the relevant data via the url. Very basic example:
# product.models.py
from django.db import models
from django.http import HttpResponseRedirect
from django.utils.translation import gettext_lazy as _
from wagtail.admin.panels import FieldPanel
from wagtail.contrib.routable_page.models import RoutablePageMixin, path
from wagtail.fields import RichTextField
from wagtail.models import Locale, Page, TranslatableMixin
from wagtail.snippets.models import register_snippet
from wagtail_localize.fields import TranslatableField
@register_snippet
class Product(TranslatableMixin, models.Model):
sku = models.CharField(max_length=10, verbose_name=_("SKU"))
title = models.CharField(max_length=100, verbose_name=_("Product Title"))
description = models.TextField(verbose_name=_("Product Description"))
panels = [
FieldPanel('sku'),
FieldPanel('title'),
FieldPanel('description')
]
translatable_fields = [
TranslatableField("title"),
TranslatableField("description"),
]
def __str__(self):
return f'{self.sku} - {self.title}'
class ProductPage(RoutablePageMixin, Page):
intro = RichTextField()
content_panels = Page.content_panels + [
FieldPanel('intro')
]
@path('')
def product_list(self, request):
products = Product.objects.filter(locale_id=Locale.get_active().id)
return self.render(
request,
context_overrides={
'products': products,
},
template="products/product_list.html",
)
@path('<str:sku>/')
def product_detail(self, request, sku):
product = Product.objects.filter(sku=sku).first()
if product:
return self.render(
request,
context_overrides={
'product': product.localized,
},
template="products/product_detail.html",
)
else:
return HttpResponseRedirect(self.url)
(The 'translatable' code is only needed for multilingual sites)
Templates:
Listing:
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block content %}
<h1>{{ page.title }}</h1>
<p> {{ page.intro|richtext }}</p>
{% for product in products %}
<h2><a href="{{page.url}}{{product.sku}}">{{ product }}</a></h2>
{% endfor %}
{% endblock content %}
Detail:
{% extends "base.html" %}
{% load wagtailcore_tags product_tags %}
{% block content %}
<h1>{{ product }}</h1>
<p>{{ product.description }}</p>
{% endblock content %}
So with this, example.com/product would give me the productindex page, example.com/product/xyz will load a details page for that product.
Upvotes: 0