Django SlugField - การ optimize URLs เว็บให้ดีต่อ SEO ของ Google

slug คือตัวช่วยที่จะทำให้ Django Website ของเรามี URL ที่ดีต่อ SEO ของ Google

Django SlugField - การ optimize URLs เว็บให้ดีต่อ SEO ของ Google

สวัสดีครับ สำหรับบทความนี้จะพามาทำความเข้าใจและสอนการใช้งาน SlugField สำหรับ Django website ของเรากันนะครับ ซึ่งจะช่วยให้เราได้ optimize ตัว URL ของเราให้ดีต่อ SEO ซึ่งนั่นก็หมายความว่าจะช่วยเพิ่มโอกาสให้บทความหรือเว็บของเราติดอันดับหน้าแรกของ Google ได้นั่นเองครับ โดยที่ไม่ต้องเสียตังค์โฆษณา เป็นการสร้างคุณค่าและ brand awareness ต่อธุรกิจของเราได้อย่างยั่งยืน

แนะนำรีซอร์สเพิ่มเติมเกี่ยวกับ SEO

ยกตัวอย่างใน Blog ของเราที่เขียน โดยเราจะใช้ ID ในการอ้างอิงถึงโพสต์หรือบทความนั้น ๆ ถามว่าดีไหม ? จริง ๆ มันก็ใช้งานได้ไม่มีปัญหาใช่ไหมครับ

ก่อนที่จะใช้ Slug

https://www.example.com/blog/1

หลังจาก update เป็น Slug

https://www.example.com/blog/django-project-tutorial

ข้อดีของการใช้ SlugField

สังเกตดูจากบทความของ STACKPYTHON เราด้านล่างครับ ทดสอบพิมพ์คำว่า “python if name main คืออะไร”

เมื่อคลิกเข้าดูบทความจะพบกับ URL นี้

https://stackpython.co/tutorial/python-if-name-main

ลองค้นหาอีกสัก 1 บทความ เช่น “web scraping python”

ถ้าคลิกเข้าไปดูบทความจะเห็น URL นี้

https://stackpython.co/tutorial/web-scraping-python-beautifulsoup-requests

จากลิ้งค์ด้านบทจะเห็นว่า Google จะเข้ามาเจอบทความของเราได้ง่ายและไวยิ่งขึ้นครับ แทนที่ปกติเราจะแสดงเป็นหมายเลขหรือ ID ในส่วนของ URL แต่เราเปลี่ยนมาเป็น keywords ที่เกี่ยวข้องให้ไปแสดงใน URLs แทน ก็จะทำให้ Google มาเจอเว็บเราได้ง่ายนั่นเองครับ

เห็นไหมครับว่าบทความของ STACKPYTHON ติดอยู่ในหน้าแรกของ Google ซึ่งก็จะช่วยให้คนเข้าถึงบทความของเราได้เยอะขึ้น ซึ่งก็จะนำไปสู่การที่คนจะสามารถเข้าไปเห็นเซอร์วิสและบริการต่าง ๆ ของเราเช่น คอร์สเรียน ได้เยอะมากยิ่งขึ้น ซึ่งจะนำไปสู่โอกาสในการที่จะทำให้เกิดการซื้อสูงขึ้นตามไปด้วยนั่นเองครับ

“แน่นอนครับว่าปัจจัยที่จะส่งผลดีต่อ SEO สำหรับบทความในเว็บไซต์ของเราเพื่อที่จะให้ไปติดหน้าแรกของ Google นั้นมีมากมาย หลากหลายปัจจัย เช่น ความเร็วของการโหลดหน้าเว็บ , การทำ keywords research, การคิดชื่อ title ของบทความที่ดี , หน้าเว็บมีการ responsive ต่อ mobile, การวางประสบการณ์ใช้งานของผู้ใช้ (UX: User Experience) และอื่น ๆ อีกหลายปัจจัย ซึ่งก็จะอยู่นอกเหนือขอบเขตของบทความนี้ ซึ่งการ optimize links หรือ URL ของเราก็เป็นอีกปัจจัยหนึ่งที่ส่งผลต่อ SEO ครับ”

บทความอ่านเพิ่มเติม : Best Practices ในการดีไซน์ URL ที่ดีต่อ SEO

1. ทำการอัปเดต Field ใน models.py

ทำการอัปเดตคอลัมน์หรือฟีลด์ใน models.py โดยกำหนดชื่อฟีลด์ตามต้องการ ในบทความนี้กำหนดเป็น slug และ Field type ใช้เป็น SlugField()

blog/models.py

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    slug = models.SlugField(null=True, blank=True)  # New
    
    def __str__(self):
        return self.title

จากนั้นทำการ makemigrations และ migrate ตามปกติ

$ python manage.py makemigrations

จะได้

Migrations for 'blog':
  blog\migrations\0006_post_slug.py
    - Add field slug to post

Migrate

$ python manage.py migrate

จะได้

  Apply all migrations: admin, auth, blog, contenttypes, django_summernote, sessions
Running migrations:
  Applying blog.0006_post_slug... OK

2. views.py and urls.py

ทำการดึงข้อมูลมาแสดงผล ตอนนี้จะยังไม่ได้ใช้ Slug ที่สร้าง แต่จะทดสอบการ Query แบบ ID ก่อนเพื่อทำการเปรียบเทียบ

โดยในฟังก์ชัน blog_details กำหนด id เป็นพารามิเตอร์ตัวที่สองถัดจาก request และก็ทำการดึงข้อมูลด้วย QuerySet แบบ get() คือดึงข้อมูลเฉพาะของโพสต์นั้น ๆ มาแสดงผลและเก็บในตัวแปร single_post จากนั้นก็รีเทิร์นค่าส่งข้อมูลออกไปแสดงผลใน template ตามปกติ

blog/views.py

from django.shortcuts import render
from .models import Post

def home(request):
    # Query all posts
    all_posts = Post.objects.all()

    return render(request, 'blog/home.html', {'all_posts': all_posts})

def blog_details(request, id):
    # Query only single post
    single_post = Post.objects.get(id=id)

    return render(request, 'blog/blog-details.html', {'single_post': single_post})

กำหนดค่า ULR ใน blog/urls.py ให้รับค่า URL พารามิเตอร์ด้วย ID ซึ่งเป็น Integer (int) เข้ามาใน URL จะได้ ’blog/int:id ตามนี้

blog/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name="home"),
    path('blog/<int:id>', views.blog_details, name="blog-details"),

]

3. templates (HTML files)

จากนั้นก็ทำการ loop ข้อมูลออกไปแสดงผลตามปกติ

home.html

{% extends "blog/base.html" %}

{% block title %}<title>Home</title>{% endblock %}

{% block content %}
    <div class="container">
        <h1>All posts</h1>
        {%  for post in all_posts %}
            <ul>
                <li><a href="#">{{ post.title }}</a></li>
            </ul>
        {%  endfor %}
    </div>
{% endblock %}

จะได้รายชื่อของแต่ละโพสต์แสดงผลในหน้า homepage

blog-details.html

% extends "blog/base.html" %}

{% block title %}<title>{{ single_post.title }}</title>{% endblock %}

{% block content %}
    <div class="container">
    {% if single_post %}
        <h1>{{ single_post.title }}</h1>
        <p>{{ single_post.body | safe }}</p>
    {% endif %}
    </div>
{% endblock %}

และนี่คือหน้า blog details ของเราครับ ซึ่งลองสังเกต URL จะเห็นว่าจะแสดงผล URL ตาม ID ซึ่งก็คือ 8


http://127.0.0.1:8000/blog/8

URL แสดงผลเป็น ID ของ โพสต์นั้น ๆ

4. เพิ่ม get_absolute_url และ save methods ใน models

blog/models.py

from django.db import models
from django.utils.text import slugify  # New
from django.urls import reverse  # New

class Post(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    slug = models.SlugFiled(null=True, blank=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('blog-details', kwargs={'slug': self.slug})

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

เปลี่ยน parameter ในฟังก์ blog_details(request, slug): จาก id ให้เป็น slug และทำการดึงข้อมูลเมธอด get() มาแบบ slug ด้วย get(slug=slug)

blog/views.py

def blog_details(request, slug):
    # Query only single post
    single_post = Post.objects.get(slug=slug)

    return render(request, 'blog/blog-details.html', {'single_post': single_post})

ทำการเปลี่ยน URL ให้เป็นการรับค่า slug แทน ID ด้วย …/slug:slug

blog/urls.py

...
path('blog/<slug:slug>', views.blog_details, name="blog-details")
...

ใน admin.py ให้ทำการเพิ่ม prepopulated_fields กำหนดเป็น dict type และกำหนด Key เป็น ‘slug’: และรับค่า (value) เป็น (‘title’,)

blog/admin.py

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    list_display = ('title',)
    prepopulated_fields = {'slug': ('title',)} 


admin.site.register(Post, PostAdmin)

จะเห็นว่ามีฟีลด์ชื่อว่า Slug ถูกเพิ่มเข้ามาและเมื่อเราได้ทดสอบพิมพ์ใน Title จะเห็นว่า Slug นั้นจะ auto gen ให้ตามชื่อ title ที่เราเขียน เช่นใจภาพด้านล่างทดสอบสร้าง Title ที่มีชื่อว่า django slug tutorial และ Slug ก็จะแสดงผลแบบอัตโนมัติ (Auto Gen) ให้ทันที

ปล. Slug URLs จะ auto generated ให้เฉพาะภาษาอังกฤษ ถ้าอยากให้เพิ่มภาษาไทย อาจจะต้องรีเสิร์ชดูเพิ่มเติมครับ แต่ภาษาอังกฤษก็เพียงพอแล้วครับ

slug จะถูกสร้างอัตโนมัติเมื่อมีการพิมพ์บน Title

ในหน้า home.html ให้เปลี่ยนการดึงข้อมูลแบบ ID มาเป็นใช้เมธอด get_absolute_url ที่ได้กำหนดไว้ในคลาส Post ใน models.py dfd

home.html

{% extends "blog/base.html" %}

{% block title %}<title>Home</title>{% endblock %}

{% block content %}
    <div class="container">
        <h1>All posts</h1>
        {%  for post in all_posts %}
            <ul>
                <li><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></li>
            </ul>
        {%  endfor %}
    </div>
{% endblock %}

จากนั้นเข้าดูหน้า homepage อีกครั้งและทำการเลือกคลิกเข้าดูโพสต์

ลองคลิกเข้าดูบทความ

สังเกตที่ URL จะเห็นว่าในตอนแรกจะแสดงเป็น …blog/8 แต่พอเปลี่ยนเป็น Slug จะได้ URL ใหม่เป็น …blog/django-introduction ที่อ่านและดูแล้วเข้าใจง่ายเพราะว่าอิงตามชื่อบทความ (Title) จึงสื่อความหมายและดีต่อ SEO ของ Google กันเรียบร้อยแล้วครับตอนนี้

URLs ก็จะสวยงามและคีเวิร์ดก็ไปแสดงบน URL เรียบร้อย

จบกันไปเรียบร้อยกับบทความ Django Slug หวังว่าทุกคนจะสามารถปรับใช้ Slug และดีไซน์ URL ของหน้าเว็บไซต์เราให้ดีต่อ SEO กันแล้วนะครับ พบกันกับบทความถัดไป อย่าลืม like, comment, share บทความนี้ได้เลยครับเพื่อซัพพอร์ตผู้เขียน See ya next article