Sitemap คือแผนผังเว็บไซต์ที่ช่วยให้ Google หรือ Search Engine รู้ว่าเว็บของเรานั้นมีเนื้อหาเกี่ยวกับอะไรบ้าง มีลิ้งค์อะไรบ้างอยู่ในเว็บไซต์ของเรา มีการเปลี่ยนแปลงของข้อมูลบ่อยแค่ไหน จะอยู่ในรูปแบบของไฟล์ XML โดยตัว Web Clawler ของ Google จะมาเก็บเกี่ยวข้อมูลในไฟล์นี้ ช่วยให้ Clawler, Bot, Spider ของ Google สแกน ค้นหาบทความ โพสต์ต่าง ๆ ในเว็บไซต์เราได้ง่ายและสะดวกยิ่งขึ้น ซึ่งแน่นอนว่าตัว Sitemap นั้นจะช่วยให้หน้าเว็บไซต์ของเราถูก rank หรือจัดอันดับใน Google ที่ดีขึ้น เรียกได้ว่า Sitemap เป็นอีกหนึ่งปัจจัยที่ส่งผลอย่างมากต่อ SEO แน่นอนว่าเมื่อเว็บไซต์หรือบทความของเราถูกจัดอันดับอยู่ในหน้าแรก ๆ โดยเฉพาะหน้า 1 นั้น จะส่งผลดีต่อธุรกิจของเราเป็นอย่างมากแบบไม่ต้องเสียตังค์โฆษณา วันนี้เราจะมาเรียนรู้ พร้อมทั้งสอนใช้งาน Django Sitemap ให้กับเว็บไซต์ Django ของเราครับ
ปล. ต้องเคยศึกษาหรือพัฒนาเว็บด้วย Django มาก่อน และสำหรับเทคนิค SEO เพิ่มเติมสำหรับเว็บที่พัฒนาด้วย Django สามารถอ่านได้เพิ่มเติมใน Django Tips ที่ควรรู้สำหรับสาวก Python Developer
"ในส่วนของการสร้างโปรเจคท์ Django นั้น จะไม่ขอลงลึกมาก เพราะว่าบทความนี้สร้างมาสำหรับ Python Developer (Django) ไม่ว่าจะเพิ่งศึกษาหรือศึกษามาบ้างแล้ว ก็สามารถอ่านได้ทำความเข้าใจได้ไม่ยาก หรือถ้ายังไม่ได้ศึกษามาก่อน ก็สามารถอ่านเพื่อดูภาพรวมได้เช่นกัน"
Start Django project
สร้างโปรเจคท์ django-admin startproject ตามด้วยชื่อโปรเจคท์คือ mysite
$ django-admin startproject mysite
Start Django App
สร้างแอปโดยใช้คำสั่ง python manage.py startapp ตามด้วยชื่อแอพ blogapp
$ cd mysite
$ python manage.py startapp blogapp
ก่อนอื่นทำการสร้างตารางเพื่อเก็บข้อมูลขึ้นมา 1 ตาราง โดยแอปตัวอย่างเบื้องต้นที่น่าจะคุ้นเคยกันดีอยู่แล้วก็คือ Blog App โดยทำการสร้าง class (ตาราง) ที่มีชื่อว่า Blog โดยทำการเพิ่ม get_absolute_url เข้ามา เพื่อที่เวลา URL ที่เขียนใน Templates มีการเปลี่ยนแปลง จะได้ไม่ต้อง Hard-code เข้าไป และทำการอิมพอร์ตฟังก์ชัน reverse จากโมดูล django.urls
# blogapp/models.py from django.db import models from django.urls import reverse # New class Blog(models.Model): title = models.CharField(max_length=120) post = models.TextField() date_created = models.DateTimeField(auto_now_add=True) date_updated = models.DateTimeField(auto_now=True) def __str__(self): return self.title def get_absolute_url(self): return reverse('post_details', args=[str(self.id)])
ใช้ตัว Default Database ที่มีมาให้ใน Django เรียบร้อยนั่นก็คือ sqlite3 ซึ่งเมื่อทำการ migrate จะได้ไฟล์ db.sqlite3 ซึ่งเก็บข้อมูลในรูปแบบของ Text File
# settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
ทำการรีจิสเตอร์แอพตามปกติโดย settings.py ในตัวแปร INSTALLED_APPS ทำการเพิ่มแอพ blogapp เข้าไปตามปกติ
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blogapp', # New
]
จากนั้นรันคำสั่งเพื่ออัพเดตฐานข้อมูล โดยใช้คำสั่ง makemigrations
$ python manage.py makemigrations
ขั้นตอนสุดท้ายคือ migrate
$ python manage.py migrate
เป็นอันเสร็จสิ้นขั้นตอนในส่วนของ Database
เขียนฟังก์ชันเพื่อ render หน้า HTML ออกไปแสดงผลพร้อมทั้งโพสต์ที่ได้ดึงข้อมูลมาจาก Database โดยฟังก์ชัน home() จะเป็นหน้า Homepage และยังดึงข้อมูลของทุกโพสต์มาแสดงหน้านี้ ส่วนฟังก์ชัน post_details() จะใช้แสดงรายละเอียดของแต่ละโพสต์
# blogapp/views.py from django.shortcuts import render from django.http import HttpResponse from .models import Blog def home(request): # Query all posts all_posts = Blog.objects.all() return render(request, "blogapp/home.html", {'all_posts': all_posts}) def post_details(request, id): # Query only one post single_post = Blog.objects.get(pk=id) return render(request, "blogapp/post-details.html", {'single_post': single_post})
ทำการกำหนด route ใหักับ App เสมือนเป็นการ register แอปของเราเข้ามาในโปรเจคท์ โดยทำการอิมพอร์ตคำสั่ง include และ blogapp.urls
# mysite/urls.py from django.contrib import admin from django.urls import path, include # New urlpatterns = [ path('', include('blogapp.urls')), # New path('admin/', admin.site.urls), ]
ทำการกำหนด route ใหักับ App เพื่อ map เข้ากับฟังก์ชันต่าง ๆ ที่เขียนไว้ใน views.py
โดยสร้างไฟล์ URL ปกติของ App เลยก็คือ urls.py
# blogapp/urls.py from django.urls import path from . import views urlpatterns = [ path('', views.home), path('post-details/<int:id>', views.post_details, name="post_details"), ]
ทำการรีจิสเตอร์ Django Model เพื่อให้แสดงผลบนหน้าแอดมิน โดยทำการอิมพอร์ต Blog เข้ามา และทำการส่งเข้าไปในฟังก์ชัน admin.site.register()
# blogapp/admin.py from django.contrib import admin from .models import Blog admin.site.register(Blog)
ทำการสร้าง Super User โดยใช้คำสั่ง
$ python manage.py createsuperuser
จากนั้นทำการใส่ username, email และ password ที่ต้องการ เป็นอันเสร็จสิ้้นขั้นตอนการสร้าง Super User ด้านล่างคือตัวอย่างการสร้าง Superuser
$ username: sonny
$ email: [email protected]
$ password: ********
$ password (again): ********
$ Superuser created successfully.
สร้างไฟล์ HTML ขึ้นมาใหม่ 2 ไฟล์ นั่นก็คือ home.html และ post-details.html ซึ่งจะถูกเก็บอยู่ในโฟลเดอร์ templates และ blogapp เป็นโฟลเดอร์สุดท้าย ตามลำดับ ซึ่งนี่คือ Best Practice ในการวาง HTML Path สำหรับ Django
blogapp/ templates/ blogapp/ home.html post-details.html admin.py models.py views.py ...
home.html
<!--home.html--> {% load static %} <!DOCTYPE html> <html> <head> <title>Home | STACKPYTHON</title> </head> <body> <h1>Hello, Django Sitemap Tutorial</h1> {% for blog in all_posts %} <ul> <li><a href="{{ blog.get_absolute_url }}">{{ blog.title }}</a></li> </ul> {% endfor %} </body> </html>
ทำการแสดงผลคำสั่งผ่าน blog.get_absolute_url แทนที่จะฮาร์ดโค้ด (Hard-code) เข้าไป
post-details.html
<!--post-details.html--> {% load static %} <!DOCTYPE html> <html> <head> <title>{{single_post.title}} | STACKPYTHON</title> </head> <body> {% if single_post %} <h1>Title: {{single_post.title}}</h1> <p>Content: {{single_post.post}}</p> {% endif %} </body> </html>
ทำการรันเซิร์ฟเวอร์
$ python manage.py runserver
เข้าดูที่ URL http://127.0.0.1:8000/ จะได้หน้า Homepage ตามภาพด้านล่าง ซึ่งตอนนี้ยังไม่มีโพสต์ใด ๆ แสดง เพราะว่ายังไม่ได้สร้างโพสต์นั่นเอง
เราสามารถที่จะทำการทดสอบสร้างโพสต์ขึ้นมาโดยที่ไม่ต้องเข้าผ่านหน้า Django Admin ซึ่งจะทำให้สามารถทดสอบ เพิ่มและดึงข้อมูลได้อย่างรวดเร็ว โดยสามารถทำผ่าน Django Shell ได้ทันที
ใช้งาน Shell
$ python manage.py shell
ทำการอิมพอร์ต Blog เข้ามาใช้งาน
>>> from blogapp.models import Blog
จากนั้นทำการสร้าง object โดยกำหนดตัวแปร obj เสร็จแล้วเรียกใช้เมธอด save() เพื่อบันทึกออปเจคท์ที่ได้สร้างขึ้นมา
>>> obj = Blog(title='Sitemap 1', post='Django sitemap post 1')
>>> obj.save()
ทดสอบดึงข้อมูลมาแสดงผล โดยเข้าถึงผ่านออปเจคท์ นั่นก็คือตัวแปร obj ที่ได้สร้างไว้ก่อนหน้า
>>> obj.title
# 'Sitemap 1'
เข้าถึง post
>>> obj.post
# 'Django sitemap post1'
เสร็จแล้วใช้คำสั่ง exit() เพื่อออกจาก Shell
สร้างโพสต์ผ่าน Django Shell
ศึกษาเพิ่มเติม (YouTube) Django QuerySet on Django Shell
Note: ถ้าอยากได้หน้า Shell ตามภาพด้านบน ให้ทำการติดตั้ง ipython
เข้าใช้งานหน้าแอดมินจะได้โพสต์มา 1 โพสต์ สามารถเพิ่มโพสต์ได้ตามต้องการ
โพสต์ที่ได้จากการสร้างผ่าน Django Shell
ทดสอบดูข้อมูลในหน้าเว็บ (ในภาพที่เห็นมีสองโพสต์ เพราะว่าได้เพิ่มโพสต์เข้ามาอีก 1 โพสต์) http://127.0.0.1:8000
หน้า Homepage มีอยู่ 2 โพสต์ในตอนนี้
http://127.0.0.1:8000/post-details/1
คลิ๊กเข้าดูรายละเอียดของแต่ละโพสต์
Django นั้นมี Sitemap เฟรมเวิร์คมาให้เรียบร้อยโดยทำการเพิ่มเข้าไป ใน INSTALLED_APPS
ไฟล์ settings.py ได้ทันที โดยมี 2 แอป นั่นก็คือ django.contrib.sites และ django.contrib.sitemaps
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites', # New
'django.contrib.sitemaps', # New
'blogapp', # Our app
]
# Define Site ID
SITE_ID = 1
โดยในส่วนนี้ไม่ต้องทำการ makemigrations สามารถ migrate ได้เลย
$ python manage.py migrate
sitemaps.py
สร้างไฟล์ขึ้นมาใหม่อีกหนึ่งไฟล์ใน blogapp หรือแอพของเรานั่นเอง โดยกำหนดชื่อไฟล์เป็น sitemaps.py
# blogapp/sitemaps.py
from django.contrib.sitemaps import Sitemap
from .models import Blog
from django.urls import reverse
class BlogSitemap(Sitemap):
changefreq = "weekly"
priority = 0.9
def items(self):
return Blog.objects.all()
def lastmod(self, obj):
return obj.date_updated
โดยการเปลี่ยนแปลงของบทบทความหรือคอนเทนต์บนเว็บมีหลายระดับดังนี้ โดยเลือกว่าจะให้ Clawler ของ Google มาเก็บข้อมูลความถึ่ประมาณไหน
อ่านเพิ่มเติม Django Sitemap Documentation
blogapp/urls.py (Final)
จะได้โค้ดส่วนสุดท้ายในส่วนของ blogapp/urls.py
# blogapp/urls.py
from django.urls import path
from . import views
from django.contrib.sitemaps.views import sitemap # New
from .sitemaps import BlogSitemap # New
# Create sitemap object, then wrap it into dict
sitemaps = {
'blogs': BlogSitemap
}
urlpatterns = [
path('', views.home),
path('post-details/<int:id>', views.post_details, name="post_details"),
path('sitemap.xml', sitemap, {'sitemaps':sitemaps}, name="sitemap") # New
]
เข้าดูในลิ้งค์ที่อยู่ของ Sitemap จะตามหลังโดเมนเนมหน้าโฮมเพจคือ /sitemap.xml ซึ่งใน Localhost จะได้ http://127.0.0.1:8000/sitemap.xml
Congrats !! สร้าง Sitemap สำเร็จแล้ว
ปล. เมื่อเว็บขึ้น Production แล้ว ต้องทำการเปลี่ยนจาก example.com เป็นชื่อโดเมนเนมของเรา โดยสามารถเปลี่ยนได้ในหน้า Django Admin
| Like | Comment | Share | >> STACKPYTHON
Reference
Django Sitemap Framework Documentation
Cover Photo
กิจกรรมที่กำลังจะมาถึง
ไม่พลาดกิจกรรมเด็ด ๆ ที่น่าสนใจ
Event นี้จะเริ่มขึ้นใน July 5, 2022
รายละเอียดเพิ่มเติม/สมัครเข้าร่วมโปรคอร์สรวมแรกของปี เรียนไพธอนครบครัน หลากหลาย ลดราคาจาก 7,900฿ เหลือ 6,900฿ พร้อมโบนัส รายละเอีดยเพิ่มเติมในลิงก์ ปล. สมาชิกที่เจอลิงก์นี้จากบทความของเรา แคปภาพมา แอดมินลดให้เพิ่มอีก 200 ครับ