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友好的网址的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 友好的 seo 网址

带有 SEO 友好网址的 Wordpress 博客 + Laravel

HTACCESS RewriteRules 带有漂亮的 SEO 网址(不允许访问物理文件位置)

重写 php 应用程序以获得 seo 友好的 url

向博客添加短网址会使 SEO 变好还是变坏? [关闭]

如何通过php查询使URL友好SEO [重复]