从开发到部署,使用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
微信公众号: