django中漂亮和seo友好的网址
Posted
技术标签:
【中文标题】django中漂亮和seo友好的网址【英文标题】:pretty and seo friendly urls in django 【发布时间】:2012-08-06 10:37:09 【问题描述】:我目前正在写一个网络博客,学习 django。我需要一个视图来显示单个博客文章,我的第一次尝试是为它创建一个 url,如下所示:
myblog.com/blog/view/1
这使用 blog-id 来识别指定的 blog-post。
现在,如果您查看许多博客/网站,您会发现它们在 url 中使用博客文章的标题,这是因为这对搜索引擎更友好,因此更容易找到。这可能看起来像这样。
myblog.com/blog/view/a-python-backup-script
我如何在 django 中实现这个?
奖金问题: 许多网站还包括帖子的月份和年份。我想这也与 SEO 有关,但这到底有什么用?
【问题讨论】:
【参考方案1】:这种类似的方法向后兼容使用数字 id 归档的 url。
在models.py中添加一个slug字段和一个保存定义:
from django.template.defaultfilters import slugify
slug = models.SlugField(default='no-slug', max_length=60, blank=True)
def save(self, *args, **kwargs):
#save a slug if there is no slug or when it's 'no-slug' (the default slug)
if not self.slug or self.slug == 'no-slug':
self.slug = slugify(self.name)
super(Project, self).save(*args, **kwargs)
在 urls.py 中添加第二个 url 模式:
#original:
url(r'^(?P<id>\d+)/$', 'project.views.view', name='view_url'),
#new pattern added under original:
url(r'^(?P<id>\d+)-(?P<slug>[-\w\d]+)/$', 'project.views.view', name='view_url'),
在views.py中让slug通过:
def view(request, mid=None, slug=None):
那么,使用这个 URL 模式所需要做的就是编辑 models.py:
def get_absolute_url(self):
return reverse('view_url', args=[self.id, self.slug])
【讨论】:
【参考方案2】:django-autoslug 非常适合此用途,并且有很多有用的选项。
【讨论】:
【参考方案3】:向您的博客模型添加一个 slug 字段。
from django.template.defaultfilters import slugify
Class Blog(models.Model):
title = models.CharField(max_length=40)
slug = models.SlugField(_('slug'), max_length=60, blank=True)
#Then override models save method:
def save(self, *args, **kwargs):
if not self.id:
#Only set the slug when the object is created.
self.slug = slugify(self.title) #Or whatever you want the slug to use
super(Blog, self).save(*args, **kwargs)
在你的 urls.py 中
(r'^blog/view/(?P<slug>[-\w]+)/$', 'app.views.blog_view'),
在views.py中
def blog_view(request, slug):
blog = Blog.objects.get(slug=slug)
#Then do whatever you want
编辑:我在 save 方法中添加了一个检查,因为您希望在创建对象时创建 slug。它不应该每次都保存。
【讨论】:
如果两篇博文标题相同怎么办? 加个ID就行了【参考方案4】:或者,如果您使用基于类的视图,您可以做的最基本的事情是:
from django.views.generic import DetailView
from models import Blog
class BlogView(DetailView):
model = Blog
template_name = "blog/blog_detail.html"
然后,url 看起来像这样:
from views import BlogView
url(r'^(?P<slug>[-w]+)/$', BlogView._as_view(), name="blog_detail"),
请注意,Django 的通用 DetailView 需要 pk 或 slug。所以在这种情况下使用 slug 与使用 pk 没有什么不同。
【讨论】:
【参考方案5】:确保您的模型实际上有一个 slug 字段:
class BlogPost(models.Model):
slug = models.SlugField(unique=True)
你有一个观点:
from django.shortcuts import get_object_or_404
def blog_detail(request, slug):
...
post = get_object_or_404(BlogPost, slug=slug)
...
render(request, "blog/blog_post.detail.html", 'blog_post' : post )
然后在你的 urls.py 中,你可以指定一个 slug:
url(r'^(?P<slug>[-w]+)/$', 'blog.views.blog_detail', , name="blog_detail"),
第一个参数是一个正则表达式,当匹配时,将运行视图 blog_detail
视图并将匹配的 slug
组从正则表达式传递到 w 视图(依次渲染并返回模板)
关于您的最后一点:我发现除了在 SEO 方面可能是积极的之外,在 url 中包含日期使我更容易一目了然地查看博客文章是否是新的。此外,在 Django 中,很容易将此方法与 date-based generic views 一起使用,这将减少您需要编写的样板视图代码的数量。这将是一个例子:
url(r'(?P<year>d4)/(?P<month>[a-z]3)/(?P<day>w1,2)/(?P<slug>[-w]+)/$',
'django.views.generic.date_based.object_detail',
template_name = "blog/detail.html", ... ,
name="blog_detail"),
【讨论】:
以上是关于django中漂亮和seo友好的网址的主要内容,如果未能解决你的问题,请参考以下文章
带有 SEO 友好网址的 Wordpress 博客 + Laravel