【问题标题】:pretty and seo friendly urls in djangodjango中漂亮和seo友好的网址
【发布时间】: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 有关,但这到底有什么用?

【问题讨论】:

    标签: django url 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>d{4})/(?P<month>[a-z]{3})/(?P<day>w{1,2})/(?P<slug>[-w]+)/$', 
                  'django.views.generic.date_based.object_detail', 
                  { template_name = "blog/detail.html", ... }, 
                  name="blog_detail"),
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-24
            • 2016-03-11
            • 2012-08-14
            • 2011-07-23
            • 2011-04-06
            • 2014-01-14
            • 2017-05-14
            相关资源
            最近更新 更多