• 从开发到部署,使用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

    微信公众号:

  • 相关阅读:
    cpu_relax
    x86汇编寄存器,函数参数入栈说明
    内核调试打印dump_stack
    内核模块中计算执行时间
    js
    JS解析+预解析相关总结
    github-如何设置SSH Key
    块级元素与行内元素的区别
    编写高质量代码——html、css、javascript
    jquery——简单的下拉列表制作及bind()方法的示例
  • 原文地址:https://www.cnblogs.com/Liqiongyu/p/5909706.html
Copyright © 2020-2023  润新知