As I mentioned in my previous post, there are a few fairly easy strategies for maintaining the stable URLs for your content when migrating from WordPress to a local Django driven blog.
Django allows you a high level of control over URL formats so it's fairly simple to design them to be compatible with WordPress URLs. Additionally WordPress has been around long enough that the standard URL re-write formats follow suggested best practices for content, so bringing your Django URLs in alignment with that is not only useful for migrating content but good practice overall.
That said the two most common formats for URLs in WordPress are:
http://<domain>/<4 digit year>/<1 or 2 digit month/<1 or 2 digit day/<slug>/
so for example the URL for the previous post linked above is…
http://www.flagonwiththedragon.com/2011/06/01/wordpress-to-django-strategies-dealing-with-WordPress-querystring-urls/
The next most common format for URLs is similar and differs mostly in how months are abbreviated:
http://<domain>/4 digit year>/<3 char month>/<1 or 2 digit day>/<slug>/
So an example of the same URL above in this format would be…
http://www.flagonwiththedragon.com/2011/jun/01/wordpress-to-django-strategies-dealing-with-WordPress-querystring-urls/
Designing urls.py in Django to accomodate this is simply:
# URL format where month format is abbreviated character format.
url(r'^(?P\d{4})/(?P\w{3})/(?P\d{1,2})/(?P[0-9A-Za-z-]+)/$', 'post_detail_alt'),
url(r'^(?P\d{4})/(?P\w{3})/(?P\d{1,2})/$', 'post_day_alt'),
url(r'^(?P\d{4})/(?P\w{3})/$', 'post_month_alt'),
# URL format where month is either one or two digits.
url(r'Word\d{4}Press\d{1,2})/(?P\d{1,2})/(?P[0-9A-Za-z-]+)/$', 'post_detail', name='post-detail'),
url(r'^(?P\d{4})/(?P\d{1,2})/(?P\d{1,2})/$', 'post_day', name='list-day'),
url(r'^(?P\d{4})/(?P\d{1,2})/$', 'post_month', name='list-month'),
url(r'^(?P\d{4})/$', 'post_year', name='list-year'),
I provide a bit more here than needed as I also include posts lists if you just use the date portion of the URL but it should be obvious.
My unscientific opinion is that digit format for all date properties in a URL is better practice and the format I see most often so I suggest using that in your own use. Using this format is also advantagous for your Django views because casting the date pieces as an int() means it can evalutate valutes like '01' and '1' in exactly the same way. TheWordPress a post detail view based on all digits then would simply be:
# Test conversion to number based dates
def post_detail(request, year, month, day, slug):
"""Returns an individual post."""
date = datetime.date(int(year), int(month), int(day))
try:
post = Post.objects.published().get(slug=slug, pub_date__year=date.year,
pub_date__month=date.month, pub_date__day=date.day)
except Post.DoesNotExist:
raise Http404
return render(request, 'blog/post_detail.xhtml', {
'post': post,
'title': post.title,
})
The view to handle URLs where months use character abbreviations is very similar and just needs a bit more to parse the date format like so…
# Detail Views
def post_detail_alt(request, year, month, day, slug):
"""
Returns an individual post. Alternate arguments for compatability with temporary URL pattern
"""
tt = time.strptime('-'.join([year, month, day]), '%Y-%b-%d')
date = datetime.date(*tt[:3])
try:
post = Post.objects.published().get(slug=slug, pub_date__year=date.year,
pub_date__month=date.month, pub_date__day=date.day)
except Post.DoesNotExist:
raise Http404
return render(request, 'blog/post_detail.xhtml', {
'post': post,
'title': post.title,
})
The above alt method is rather sloppy on my part really and violates DRY principles so at some future date I could refactor the alt method to be more lean like so…
def post_detail_alt(request, year, month, day, slug):
"""
Returns an individual post. Alternate arguments for compatability with temporary URL pattern
"""
tt = time.strptime('-'.join([year, month, day]), '%Y-%b-%d')
date = datetime.date(*tt[:3])
return post_detail(request, date.year, date.month, date.day)
That's really all you need. If you're migrating content from WordPress and used those URL formats all your content should map. If you're just starting out with your blog the concepts here are sound for starting right from the beginning.