從開發到部署,使用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

微信公眾號:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM