6/29/2016

用 Django 开发个人博客

参考资料

Django 搭建开发环境

  • 首先,安装 python 2.7,过程不在赘述;
  • 安装 django 1.8.5
$ sudo pip install django==1.8.5

检查是否安装成功:

$ python

>>> import django
>>> print django.VERSION

最后,按 ctrl + d 可以退出 python 环境。

创建工程

$ django-admin.py startproject firstblog

查看工程目录结构:

$ tree

创建应用模块

一个工程中可以创建多个应用app,一个app就是一个功能模块,下面创建一个 blog 应用。

$ python manage.py startapp blog

然后,需要将新增的app添加到工程中去,打开 firstblog/settring.py 配置文件,增加一行:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
)

启动工程

firstblog 工程目录下,输入命令:

$ python manage.py runserver

打开浏览器,输入:

127.0.0.1:8000

数据库设置

  • 安装 mysql 数据库

参考:Ubuntu + Python 学习之路

然后,安装 navicat for mysql 方便管理数据库。

  • 新建 blog 数据库
$ mysql -u root -p

mysql> create database blog default charset=utf8;

打开 firstblog/settings.py 文件,修改:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'blog',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

...

TIME_ZONE = 'Asia/Shanghai'
  • 新建表

打开 blog/models.py 文件,添加:

# -*- coding: utf-8 -*-
from django.db import models
 
# Create your models here.
 
class Tag(models.Model):
    tag_name = models.CharField('标签', max_length=50)
    tag_cn_name = models.CharField('中文名字', max_length=50, blank=True)
 
    def __unicode__(self):
        return self.tag_name
 
 
class Article(models.Model):
    title = models.CharField('标题', max_length=100)
    tag = models.ManyToManyField(Tag, max_length=50, blank=True)
    date_time = models.DateTimeField('日期', auto_now_add=True)
    content = models.TextField('内容', blank=True, null=True)
 
    def __unicode__(self):
        return self.title
 
    class Meta:
        verbose_name = '文章'
        verbose_name_plural = '文章'
        ordering = ['-date_time']

然后,打开终端,输入:

$ python manage.py makemigrations
$ python manage.py migrate

创建后台管理用户:

$ python manage.py createsuper
Username (leave blank to use 'lyj'): admin
Email address: admin@123.com
Password: 
Password (again): 
Superuser created successfully.

blog/admin.py 中注册这两个表:

from django.contrib import admin
from blog.models import Tag, Article
 
# Register your models here.
 
admin.site.register(Tag)
admin.site.register(Article)

在浏览器中输入 127.0.0.1:8000/admin,会出现登陆界面。

view 和 url (1)

  • 打开 firstblog/urls.py 文件,添加一行打开首页的代码:
from django.conf.urls import include, url
from django.contrib import admin
import settings

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', 'blog.views.home', name='home'),
]
  • 接着打开 blog/views.py,添加 home 函数:
from django.http import HttpResponse

# Create your views here.

def home(request):
 
    return HttpResponse("<label style='color: ff0000'>Hello World</label>")
  • 然后,启动服务,在浏览器输入 127.0.0.1:8000,可以看到会输出:
Hello World

view 和 url (2)

  • view 中使用数据库,修改 home 函数:
from django.shortcuts import render
#from django.http import HttpResponse
from blog.models import Article, Tag

# Create your views here.

def home(request):
    post_list = Article.objects.all()
 
    #return HttpResponse("<label style='color: ff0000'>Hello World</label>")
    return render(request, 'blog/index.html', {'post_list':post_list})

此功能是获取所有的文章列表。

  • 再定义一个文章接收函数:
def get_articles(request, tag_name):
    post_list = Article.objects.filter(tag_name = tag_name)
    
    return render(request, 'blog/index.html', {'post_list':post_list})
  • 根据文章的 id 获取文章的内容:
def detail(request, id):
    post = Article.objects.get(id = str(id))
    return render(request, 'blog/detail.html', {'post':post})
  • blog/ 目录下建立 url.py 文件,添加代码:
# -*- coding: utf-8 -*-

from django.conf.urls import url

urlpatterns = [
    url(r'^$', 'blog.views.home'),
    url(r'^(?P<id>\d+)/$', 'blog.views.detail', name='detail'),
    url(r'^(?P<tag_name>\w+)/$', 'blog.views.get_articles', name='get_articles'),
]

模板

  • firstblog/ 目录下新增一个 templates 目录,与 blog 目录同级,在 templates 目录下新建一个 blog 目录。

  • 由于前台页面中 html, css, js 等开发起来比较复杂,现在基本都用一些比较强大的工具,比如 bootstrap,但鉴于这个例子比较简单,就用一个轻量的 pure 框架。

pure 框架安装参考:Ubuntu + Python 学习之路

  • 接着修改 firstblog/settings.py 文件:
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        #'DIRS': [],
        'DIRS': (os.path.join(BASE_DIR, 'firstblog/templates/'),),	# 路径要写全
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
  • 下面实现一个简单的功能,把之前从数据库中获取的文章列表在模板中显示出来,在 templates/blog/ 下创建 index.html
<!--index.html-->
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="Keywords" content="python,django,django教程,服务器开发,web开发,博客开发" />
        <meta name="description" content="东杰网站.">
 
        <title>东杰网</title>
 
        <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
        <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/grids-responsive-min.css">
        <link rel="stylesheet" href="http://picturebag.qiniudn.com/blog.css">
 
    </head>
 
    <body>
        <div id="layout">
            <div class="sidebar pure-u-1 pure-u-md-1-4">
                <div>
                    <h1>Dong&Jie Blog</h1>
                    <h2>东杰的网站</h2>
 
                </div>
            </div>
 
 
            <div class="content pure-u-1 pure-u-md-3-4">
              <div>
                {% for post in post_list %}
                    <section>
                        <header>
                            <h2><a href="" target="_blank">{{ post.title }}</a></h2>
 
                                <p>
                                    日期:  <label href="#">{{ post.date_time |date:"Y /m /d H:i:s"}}</label>
                                </p>
                        </header>
                    </section>
                {% endfor %}
              </div>
            </div>
        </div>
    </body>
</html>
  • 模板继承:

templates/blog/ 下创建 base.html 文件:

<!--base.html-->
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="Keywords" content="python,django,django教程,服务器开发,web开发,博客开发" />
        <meta name="description" content="东杰网站.">
 
        <title>东杰网</title>
 
        <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
        <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/grids-responsive-min.css">
        <link rel="stylesheet" href="http://picturebag.qiniudn.com/blog.css">
        <link rel="stylesheet" href="http://picturebag.qiniudn.com/monokai.css">
 
    </head>
 
    <body>
        <div id="layout">
            <div class="sidebar pure-u-1 pure-u-md-1-4">
                <div>
                    <h1>Dong&Jie Blog</h1>
                    <h2>东杰的网站</h2>                   
                </div>
            </div>
 
            <div class="content pure-u-1 pure-u-md-3-4">
                <div>
                    {% block content %}
                    {% endblock %}
                </div>
            </div>
        </div>
    </body>
</html>

然后,改写 index.html

<!--home.html-->
{% extends "blog/base.html" %}
 
{% block content %}
<div class="posts">
    {% for post in post_list %}
        <section class="post">
            <header class="post-header">
                <h2 class="post-title"><a href="" target="_blank">{{ post.title }}</a></h2>
 
                    <p class="post-meta">
                        日期:  <label class="post-author" href="#">{{ post.date_time |date:"Y /m /d H:i:s"}}</label>
                    </p>
            </header>
        </section>
    {% endfor %}
 
</div><!-- /.blog-post -->
{% endblock %}
  • 点击文章标题,显示文章详情:
    首先,修改 index.html,将标题的 href 改为:
<h2 class="post-title"><a href="{% url "detail" id=post.id %}" target="_blank">{{ post.title }}</a></h2>

firstblog/urls.py 中添加:

url(r'^blog/', include('blog.urls')),

blog/urls.py 中添加:

url(r'^(?P<id>\d+)/$', 'blog.views.detail', name='detail'),

templates/blog/ 下新建一个 detail.html

<!--detail.html-->
{% extends "blog/base.html" %}
{#{% load custom_markdown %}#}
 
{% block content %}
<div class="posts">
    <section class="post">
        <header class="post-header">
            <h2 class="post-title"><a href="">{{ post.title }}</a></h2>
 
                <p class="post-meta">
                    日期:  <label class="post-author">{{ post.date_time |date:"Y /m /d H:i:s"}}</label>
                </p>
        </header>
 
        <div >
             {{ post.content}}
        </div>
    </section>
</div>
{% endblock %}

启动服务,在浏览器中打开,点击标题,就可以看到文章详情了。

后台 Admin

  • 实现后台富文本编辑界面

选择百度的 Ueditor 编辑器:github Ueditor

下载后,把里面的 DjangoUeditor-master 中的 DjangoUeditor 文件夹放到跟 blogtemplates 同一级目录

修改 firstblog/settrings.py

INSTALLED_APPS = (
    ...
     
    'blog',
    'DjangoUeditor',
)

在最下面添加如下代码,保证可以上传图片:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static')
 
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "common_static"),
)
 
# upload folder
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

firstblog/urls.py 添加:

url(r'^ueditor/', include('DjangoUeditor.urls' )),

在最下面添加:

import settrings

...

if settings.DEBUG:
    from django.conf.urls.static import static
    urlpatterns += static(
        settings.MEDIA_URL, document_root = settings.MEDIA_ROOT
    )

最后,修改 blog/models.py

from DjangoUeditor.models import UEditorField
 
class Article(models.Model):
 
           。。。省略其他代码
            
    content = UEditorField('内容', height=500, width=1000,
        default=u'', blank=True, imagePath="uploads/images/",
        toolbars='besttome', filePath='uploads/files/')
  • 前台的显示

首先,修改 templates/blog/base.html,在 <head> 中添加:

<link href="/static/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/static/ueditor/third-party/SyntaxHighlighter/shCore.js"></script>
<script type="text/javascript">
    SyntaxHighlighter.all();
</script>

然后,将 templates/blog/detail.html 中的:

<div >
     {{ post.content}}
</div>

改为:

<div >
    {{ post.content|safe }}
</div>

safe 把服务器传过来的格式转换为html 格式。

Over!

没有评论:

发表评论

Cloudflare R2 + WebP Cloud + uPic 免费图床方案

搭建免费全球可访问的图床方案:Cloudflare R2 + WebP Cloud + uPic