django: ลองทำ Blog

 

เอามาจาก Falling Bullets - Blog - WordPress Clone in 27 Seconds (Part 1 of 40)

เราชื่อ webmaster
# su webmaster

เราตั้งให้ไฟล์ของเราอยู่ใน ~/django
$ cd ~/django

ก่อนเริ่ม ให้ลบ database ชื่อ mysite ที่เราเคยทำไว้ออกก่อน
แล้วจึงค่อยสร้างใหม่แบบว่าง ๆ
$ psql template1 -U superx
Password for user superx <<<--- SUPERX-PASSWORD
template1=# DROP DATABASE mysite;
template1=# CREATE DATABASE mysite;
template1=# \q

เริ่มสร้างโปรเจกต์
$ django-admin.py startproject mysite
$ cd mysite

แก้ไข settings.py ให้เรียบร้อย
$ vi settings.py

...
DATABASE_ENGINE = 'postgresql'
DATABASE_NAME = 'mysite'
DATABASE_USER = 'superx'
DATABASE_PASSWORD = 'SUPERX-PASSWORD'
DATABASE_PORT = '5432'
...
TIME_ZONE = 'Asia/Bangkok'
...

สร้างแอปพลิเกชั่นชื่อ blog
$ django-admin.py startapp blog

แก้ไข models.py เพื่อสร้าง table
$ vi blog/models.py

from django.db import models

class Tag(models.Model):
    name = models.CharField(maxlength=50, core=True)
    slug = models.SlugField(prepopulate_from=("name",))

    class Admin:
        pass

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return "/blog/tags/%s/" % (self.slug)

class Entry(models.Model):
    title = models.CharField(maxlength=200)
    slug = models.SlugField(
        unique_for_date='pub_date',
        prepopulate_from=('title',),
        help_text='Automatically built from the title.'
    )
    summary = models.TextField(help_text="One paragraph. Don't add <p> tag.")
    body = models.TextField()
    pub_date = models.DateTimeField()
    tags = models.ManyToManyField(Tag, filter_interface=models.HORIZONTAL)

    class Meta:
        ordering = ('-pub_date',)
        get_latest_by = 'pub_date'

    class Admin:
        list_display = ('pub_date', 'title')
        search_fields = ['title', 'summary', 'body']

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return "/blog/%s/%s/" % (self.pub_date.strftime("%Y/%b/%d").lower(), self.slug)

แก้ไข urls.py ให้สามารถเรียกไดเรกทอรี่เลียนแบบ Wordpress
$ vi urls.py

from django.conf.urls.defaults import *
from mysite.blog.models import Entry

blog_dict = {
    'queryset': Entry.objects.all(),
    'date_field': 'pub_date',
}

urlpatterns = patterns('',
    (r'^blog/(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'django.views.generic.date_based.object_detail', dict(blog_dict, slug_field='slug')),
    (r'^blog/?$', 'django.views.generic.date_based.archive_index', blog_dict),
)

รัน syncdb ครั้งนึง เพื่อสร้าง table
$ python manage.py syncdb
...
Would you like to create one now? (yes/no): <<<--- yes
Username (Leave blank to use 'webmaster'): <<<--- [ENTER]
E-mail address: <<<--- webmaster@example.com
Password: <<<--- WEBMASTER-PASSWORD
Password (again): <<<--- WEBMASTER-PASSWORD
Superuser created successfully.
...

แก้ไข settings.py ให้มาใช้ template ของเรา
$ vi settings.py

...
TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates".
    # Always use forward slashes, even on Windows.
    "/home/webmaster/django/mysite/templates"
)
...

สร้าง template หลัก ชื่อ base.html ในไดเรกทอรี่ ~/django/mysite/templates
$ mkdir templates
$ vi templates/base.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>My Site - {% block title %}{% endblock %}</title>

    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
    <div id="header">
        <h1><a href="/">My Interweb Tubes Blog</a></h1>

        <h2>It's not a truck!</h2>

        <ul id="nav">
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
            <li><a href="#">Photos</a></li>
            <li><a href="/links/">Links</a></li>
            <li><a href="/portfolio/">Work</a></li>
            <li><a href="/colophon/">Colophon</a></li>
        </ul>
    </div>
    <div id="content">
        {% block content %}

        {% endblock %}
    </div>
</body>
</html>

สร้าง template ย่อย สำหรับดู Entry archive
$ mkdir templates/blog
$ vi templates/blog/entry_archive.html

{% extends "base.html" %}

{% block title %}Latest Blog Entries{% endblock %}

{% block content %}
    <h1>Latest Blog Entries</h1>

    <ol id="object-list">
        {% for object in latest %}
            <li>
                <h2><a href="{{ object.get_absolute_url }}">{{ object.title|escape }}</a></h2>
                <p class="post-date">{{ object.pub_date|date:"F j, Y" }}</p>
                <p class="summary">{{ object.summary }}</p>
            </li>
        {% endfor %}
    </ol>
{% endblock %}

และอีกอันสำหรับดูรายละเอียด
$ vi templates/blog/entry_detail.html

{% extends "base.html" %}

{% block title %}Blog - {{ object.title|escape }}{% endblock %}

{% block content %}
    <h1>{{ object.title|escape }}</h1>

    <dl>
        <dt>Posted On:</dt>
        <dd>{{ object.pub_date|date:"F j, Y" }}</dd>
        <dt>Tags:</dt>
        <dd>
            {% for tag in object.tags.all %}
                <a href="{{ tag.get_absolute_url }}">{{ tag.name }}</a>{% if not forloop.last %}, {% endif %}
            {% endfor %}
        </dd>
    </dl>

    {{ object.body }}
{% endblock %}

แก้ไข settings.py อีกครั้ง ให้รับโมดูล blog และโมดูล admin
$ vi settings.py

...
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'mysite.blog',
    'django.contrib.admin',
)

syncdb อีกครั้ง
$ python manage.py syncdb

เสร็จแล้ว ลองรันได้เลยด้วยคำสั่ง
$ python manage.py runserver 192.168.1.5:8000

สร้างเนื้อหา blog ได้จาก http://192.168.1.5:8000/admin
โดยล๊อกอินในชื่อ webmaster และสร้างเนื้อหาในหมวด blog

ดูเนื้อหาที่สร้างแล้วที่ http://192.168.1.5:8000/blog