0๐
Iโm not sure if you can integrate this with wagtail but here is an example of how you can achieve with django :
- Update your model to generate automatically the slug (E.g : based on title) in
blog/models.py
:
from django.db import models
from django.utils.text import slugify
from django.utils.timezone import now
class Post(models.Model):
# your attributes
date = models.DateTimeField(default=now())
title = models.CharField(max_length=250)
slug = models.SlugField()
def save(self):
"""
Generate and save slug based on title
"""
super(Post, self).save()
self.slug = slugify(self.title)
super(Post, self).save()
- Add a new url in your blog app (
blog/urls.py
) :
url(r'^(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/(?P<slug>[\w-]+)$', views.post_details)
- Define the view to get the post in
blog/views.py
:
def post_details(request, year, month, day, slug):
post = Post.objects.get(slug=slug, date__year=year, date__month=month, date__day=day)
# do what you want with this post
0๐
Here is a more Wagtail specific way to implement this solution, it assumes you also have a BlogIndexPage that contains all the blog pages underneath. Although this would work even if your BlogPages exist under the HomePage, just move your route method accordingly.
Overview:
- We will be updating the sub-URLs on the BlogPageIndex (or whatever page that your blog pages are located within). We do this by adding the mixin RoutablePageMixin.
- We can then use
@route
as a decorator over a method on BlogPageIndex for any kind of custom views we want. - Finally, we need to update our BlogPage model so its normal URL will follow our new URL mapping. We do this by overriding the
set_url_path
on our BlogPage. - This will use the normal
slug
field from the BlogPage model and the fielddate_published
to generate the newurl_path
.
See example /myapp/models.py
from django.shortcuts import get_object_or_404
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from wagtail.wagtailcore.models import Page
class BlogPage(Page):
# using date_published instead of date to reduce ambiguity
date_published = models.DateField(
"Date post published", blank=True, null=True
)
# ...other fields: main_image, intro, body
# ...search_fields
# ...content_panels
# override the set_url_path method to use generate different URL
# this is updated on save so each page will need to be re-published
# old URL will still work
def set_url_path(self, parent):
# initially set the attribute self.url_path using the normal operation
super().set_url_path(parent=parent)
self.url_path = self.url_path.replace(
self.slug, '{:%Y/%m/%d/}'.format(self.date_published) + self.slug
)
class BlogIndexPage(RoutablePageMixin, Page):
# note - must inherit RoutablePageMixin AND Page
# ...other fields
# ...search_fields
# ...content_panels
# route for sub-pages with a date specific URL for posts
# this will NOT make a list of pages at blog/2018 just specific blogs only
@route(r'^(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/(?P<slug>[\w-]+)/?$')
def blog_page_by_date(self, request, year, month, day, slug, name='blog-by-date'):
"""Serve a single blog page at URL (eg. .../2018/01/23/my-title/)"""
blog_page = get_object_or_404(
BlogPage,
date_published__year=year,
date_published__month=month,
date_published__day=day,
slug=slug
)
return blog_page.serve(request)
# Speficies that only BlogPage objects can live under this index page
subpage_types = ['BlogPage']
Caveats:
- Each existing blog page will need to be re-saved to trigger the updates to the url_path.
- The original url_path will still work and not redirect, it is possible to add a redirect by overriding the
serve
method and checking if an old URL has been used, then redirect. - This does not consider any SEO implications of having multiple URLs for pages.
๐คLB Ben Johnston
- [Django]-Unknown command: 'collectstatic' Django 1.7
- [Django]-Is it possible to get an interactive django shell using the test database?
- [Django]-Getting Http403 when saving files through django s3 middleware (but can save using boto in shell)
- [Django]-Django makemigrations No changes detected in app
Source:stackexchange.com