从开发到部署,使用django创建一个简单可用的个人博客

本文参考于:

简书-Django搭建简易博客教程:http://www.jianshu.com/p/d15188a74104

自强学堂-Django基础教程:http://www.ziqiangxuetang.com/django/django-tutorial.html

Django官方文档中文翻译版:http://python.usyiyi.cn/django/index.html

 

本文主要是一步一步教大家如何使用Django构建一个自己的博客,基础的django不会讲的太详细,想要详细学习django的同学可以参考上面三个教程

本文的所有代码将托管于github:https://github.com/w392807287/django_blog_tutorial

本文开发环境:

  • django 1.8.3
  • ubuntu 16.04
  • python 2.7.12

迈出第一步

首先,安装django,这里我们使用的是1.8.3版本

sudo pip install django==1.8.3

  

创建django项目并开始一个新的app,如果是使用pycharm的同学可跳过

django-admin startproject tutorial
cd tutorial
python manage.py startapp blog

  

在settings.py 中加入blog,然后

python manage.py migrate
python manage.py runserver

  

尝试访问http://127.0.0.1:8000/

访问成功!

为你的博客创建一个模型

迈出第一步之后,我们已经有一个可以访问的项目了,现在我们需要为其创建模型,模型是Django提供一个抽象层(Models)以构建和操作你的web应用中的数据。

打开blog/models.py文件

#coding:utf8
from __future__ import unicode_literals

from django.db import models

# Create your models here.

class Article(models.Model):
    title = models.CharField(u"博客标题",max_length = 100)        #博客标题
    category = models.CharField(u"博客标签",max_length = 50,blank = True)       #博客标签
    pub_date = models.DateTimeField(u"发布日期",auto_now_add = True,editable=True)       #博客发布日期
    update_time = models.DateTimeField(u'更新时间',auto_now=True,null=True)
    content = models.TextField(blank=True, null=True)  # 博客文章正文

    def __unicode__(self):
        return self.title

    class Meta:     #按时间下降排序
        ordering = ['-pub_date']
        verbose_name = "文章"
        verbose_name_plural = "文章"

  

这样我们就创建了第一个属于我们博客的模型——文章。

然后,然后我们就同步数据库咯

python manage.py makemigrations
python manage.py migrate

  

登陆管理后台

首先我们先创建一个超级用户,用来登陆后台管理

python manage.py createsuperuser

  

然后在blog/admin.py中加入代码:

#coding:utf8

from django.contrib import admin
from blog.models import Article
# Register your models here.

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title','pub_date')

admin.site.register(Article,ArticleAdmin)

  

现在

python manage.py runserver

  

就能访问了,管理页面在http://127.0.0.1:8000/admin/

但是现在页面不是那么好看,而且界面是英文的,那么我们需要做一些修改

首先我们先安装一个bootstrap的插件

(sudo) pip install bootstrap-admin

  

然后在tutorial/settings.py中更改一些代码

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

  

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

  

红色字样是修改后的,首先插入bootstrap的管理页面插件,然后语言设置为中文,时区更改为中国。

现在运行就能看到一个正常的界面了

然后可以尝试添加一篇博客

集成 DjangoUeditor 编辑器及静态文件的处理

以上,界面是好看了不少,但是这个文章是不是有点简陋啊,只能写文本性的东西。我们现在来给它加一点点东西。我们下面来集成百度的Ueditor 到我们的系统:

https://github.com/twz915/DjangoUeditor3 

上面是DjangoUeditor 包,可以下载zip或者直接clone,将里面的额DjangoUeditor 直接放到项目根目录,

ls
blog  db.sqlite3  DjangoUeditor  manage.py  README.md  templates  tutorial

  

然后在tutorial/settings.py中加入

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

  这是为了让django能识别这个模块

在tutorial/url.py中加入

from django.conf.urls import include, url
from django.contrib import admin
from DjangoUeditor import urls as djud_urls
from django.conf import settings

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^ueditor/',include(djud_urls)),
]

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

  这是为了让django能访问编辑器模块  

然后在tutorial/settings.py中加入

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')

#公共的static文件
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,"common_static"),
    os.path.join(BASE_DIR,"media"),
)

#upload floder
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR,'media')

STATICFILES_FINDERS = ("django.contrib.staticfiles.finders.FileSystemFinder",
                       "django.contrib.staticfiles.finders.AppDirectoriesFinder",)

  这是静态文件的配置,很多初学django的同学会在这里碰到坑。下面一个一个解释一下

  • STATIC_URL 这个是放置静态文件的地方,django会默认在这个文件夹中寻找需要的静态文件,很多教程教大家上来就把静态文件塞这里面其实这并不是一个好的处理方法,因为在发布前需要统一收集静态文件的时候会从各个文件夹中收集静态文件放入这个文件夹中,期间有可能会覆盖掉原来的文件。
  • STATIC_ROOT 这个就是静态文件相对于系统的目录
  • MEDIA_URL 一般会将上传的文件放入这个文件夹
  • MEDIA_ROOT 同STATIC_ROOT
  • STATICFILES_DIRS 这一个元组,里面放置开发时静态文件自动搜寻的目录,我们在开发是先建一个common_static即公用的静态文件夹,在里面放我们自己的静态文件,等最后使用静态文件收集命令一并处理。

然后我们更改blog/models.py 中的模型

from DjangoUeditor.models import UEditorField


content = UEditorField(u"文章正文",height=300,width=1000,default=u'',blank=True,imagePath="uploads/blog/images/",
                           toolbars='besttome',filePath='uploads/blog/files/')

  

跟新数据库

python manage.py makemigrations
python manage.py migrate

 

然后运行一下

好了,现在我们的编辑器就是一个能写文字能传图还能自动保存的“厉害编辑器”了,科科。

至此,自己用的算是告一段落,那么,作为一个博客,时需要给别人看的啊,所以下面写一些给别人看的东西。

 

views和urls

我们在blog/views.py中加入:

def Test(request):
    return HttpResponse("just a test")

  

在blog中添加urls.py:

#coding:utf8
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^test/',views.Test,name="blog_test"),
]

  

在tutorial的urls中引入blog的urls:

import blog.urls as blog_url

urlpatterns = [
    url(r'^blog/',include(blog_url)),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^ueditor/',include(djud_urls)),
]

  

运行后可以正常访问,返回just a test。

我们尝试这通过视图views访问数据库,更改/blog/views.py:

from blog.models import Article

def Test(request):
    post = Article.objects.all()
    return HttpResponse(post[0].content)

  

如果你刚在后台添加了文章那么就能看到它了!

使用Template来展示

在项目目录下有一个名叫templates的文件夹,如果没有你就建一个咯又花不了多大劲儿。

新建一个html文件templates/blog/test.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Just test template</title>
        <style>
            body {
               background-color: red;
            }
            em {
                color: LightSeaGreen;
            }
        </style>
    </head>
    <body>
        <h1>Hello World!</h1>
        <strong>{{ current_time }}</strong>
    </body>
</html>

修改views.py :

def Test(request) :
    return render(request, 'blog/test.html', {'current_time': datetime.now()})

  

现在运行访问http://127.0.0.1:8000/blog/test就能看到hello world 和当前时间.

现在我们新建3个html文件

base.html:

<!doctype html>
<html lang="zh-hans">
<head>
    <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="A layout example that shows off a blog page with a list of posts.">
    <title>李琼羽的博客</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css">
    <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/grids-responsive-min.css">
    <link rel="stylesheet" href="http://picturebag.qiniudn.com/blog.css">
</head>
<body>
<div id="layout" class="pure-g">
    <div class="sidebar pure-u-1 pure-u-md-1-4">
        <div class="header">
            <h1 class="brand-title"><a href="{% url 'blog_home' %}">Angelo Li Blog</a></h1>
            <h2 class="brand-tagline">李琼羽 - Angelo Li</h2>
            <nav class="nav">
                <ul class="nav-list">
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">主页</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">归档</a>
                    </li>
                    <li class="nav-item">
                        <a class="pure-button" href="/">Github</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-error pure-button" href="/">微博</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">专题</a>
                    </li>
                    <li class="nav-item">
                        <a class="button-success pure-button" href="/">About Me</a>
                    </li>
                </ul>
            </nav>
        </div>
    </div>


    <div class="content pure-u-1 pure-u-md-3-4">
        <div>
            {% block content %}
            {% endblock %}
            <div class="footer">
                <div class="pure-menu pure-menu-horizontal pure-menu-open">
                    <ul>
                        <li><a href="/">About Me</a></li>
                        <li><a href="/">微博</a></li>
                        <li><a href="/">GitHub</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</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="{% url 'blog_detail' id=post.id %}">{{ post.title }}</a></h2>

                    <p class="post-meta">
                        Time:  <a class="post-author" href="#">{{ post.date_time |date:'Y /m /d'}}</a> <a class="post-category post-category-js" href="#">{{ post.category }}</a>
                    </p>
            </header>

                <div class="post-description">
                    <p>
                        {{ post.content|safe }}
                    </p>
                </div>
                <a class="pure-button" href="{% url 'blog_detail' id=post.id %}">Read More >>> </a>
        </section>
    {% endfor %}
</div><!-- /.blog-post -->
{% endblock %}

  post.html

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

{% block content %}
<div class="posts">
        <section class="post">
            <header class="post-header">
                <h2 class="post-title">{{ post.title }}</h2>

                    <p class="post-meta">
                        Time:  <a class="post-author" href="#">{{ post.date_time|date:'Y /m /d'}}</a> <a class="post-category post-category-js" href="#">{{ post.category }}</a>
                    </p>
            </header>

                <div class="post-description">
                    <p>
                        {{ post.content|safe }}
                    </p>
                </div>
        </section>
</div><!-- /.blog-post -->
{% endblock %}

  

其中,home.html和post.html继承于base.html

更改blog/views.py

#coding:utf8

from django.shortcuts import render
from django.http import HttpResponse
from blog.models import Article
from datetime import datetime
from django.http import Http404
# Create your views here.

def home(request):
    post_list = Article.objects.all()  # 获取全部的Article对象
    return render(request, 'blog/home.html', {'post_list': post_list})

def Test(request):
    return render(request,'blog/test.html',{'current_time': datetime.now()})

def Detail(request,id):
    try:
        post = Article.objects.get(id=str(id))
    except Article.DoesNotExist:
        raise Http404
    return render(request,'blog/post.html',{'post':post})

  blog/urls.py

#coding:utf8
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^post/(?P<id>\d+)/$',views.Detail,name="blog_detail"),
    url(r'^home/',views.home,name="blog_home"),
    url(r'^test/',views.Test,name="blog_test"),
]

  tutorial/urls.py

from django.conf.urls import include, url
from django.contrib import admin
import blog.urls as blog_url
from DjangoUeditor import urls as djud_urls
from django.conf import settings

urlpatterns = [
    url(r'^blog/',include(blog_url)),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^ueditor/',include(djud_urls)),
]

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

  运行访问http://127.0.0.1:8000/blog/home/

 

以上,开发过程已经完成,当然你可以自己加入需要的东西,比如评论什么的。

使用uWSGI+nginx部署Django项目

详细步骤见http://www.cnblogs.com/Liqiongyu/articles/5893780.html

这里只讲主要的步骤

首先安装:

sudo apt-get install nginx
sudo pip install uwsgi

  

更改nginx配置文件

sudo vim /etc/nginx/sites-available/default

  如下

upstream django {
    server unix:///home/ubuntu/blogsite/mysite.sock; # for a file socket
}
 
server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;
 
        root /usr/share/nginx/html;
        index index.html index.htm;
 
        # Make site accessible from http://localhost/
        server_name localhost;
 
        charset utf-8;
 
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
 
        client_max_body_size 75M;
 
        location /media {
                alias /home/ubuntu/blogsite/media;
        }
 
        location /static {
                alias /home/ubuntu/blogsite/static;
        }
 
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ =404;
                # Uncomment to enable naxsi on this location
                # include /etc/nginx/naxsi.rules
                uwsgi_pass      django;
                include         /etc/nginx/uwsgi_params;
        }
}

  

上面的/home/ubuntu/blogsite是我的项目目录,全部改成你自己的就OK
然后执行命令:
python manage.py collectstatic

  这是用来收集静态文件的,上面有提到


然后在项目根目录添加mysite_uwsgi.ini文件:
[uwsgi]
 
# Django-related settings
# the base directory (full path)
chdir           = /home/ubuntu/blogsite
# Django's wsgi file
module          = blogsite.wsgi
# the virtualenv (full path)
# home            = /path/to/virtualenv
 
# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 2
# the socket (use the full path to be safe
socket          = /home/ubuntu/blogsite/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = true

  然后修改tutorial/settings.py :

DEBUG = False

ALLOWED_HOSTS = ['*']

解除debug模式,allowed_hosts中添加你的域名,这里为方便填*  

然后重启nginx,运行uwsgi

sudo service nginx restart
uwsgi --ini mysite_uwsgi.ini

  访问http://youdomain.com/blog/home

  代码更改了url后可以直接访问youdomain.com

 

以上,网站就能正常访问。有问题欢迎微信留言

代码地址:https://github.com/w392807287/django_blog_tutorial

欢迎多来访问博客:http://liqiongyu.com/blog

微信公众号:

 

posted @ 2016-09-26 16:38  李琼羽  阅读(29591)  评论(4编辑  收藏  举报