周末整理旧日志发现在 2013 年学习 Django 时写的 《Django:快速搭建简单的Blog》一文得到不少网友的引用,激励了我的创作热情。所以就把旧文重新写一下,毕竟现在的 Django 已经更新到 3.1.1 版本了。
本文分两部分:
第一部分是介绍如何在 Ubuntu 20.04 上搭建 Django 开发环境;
第二部分是介绍快速地使用 Django 构建一个简单的 Blog ,供入门参考。
在 Ubuntu 20.04 搭建 Django 开发环境
1. 设置 Python
Ubuntu 20.04 中,默认的 Python 版本为 Python3, 在终端只能通过 python3 命令调用 Python解释器,不能像以往的 Ubuntu 发行版本那样直接通过 python 命令调用。
检查 python 命令:
为了方便后续工作,可以为 Python3 创建符号链接把 python3 配置为直接通过 python 命令调用。
使用以下命令为 Python3 创建一个符号链接:
1
| $ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
至此,Python3 的配置已经完成。
2. Pip 包管理程序的安装与配置
使用 apt 命令安装 python3-pip:
1
| $ sudo apt install python3-pip -y
|
python3-pip 安装完毕后,把 pip3 设置为默认的 pip 版本:
sudo update-alternatives --installpip /usr/bin/pip3 11
| $ sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
|
检查 pip 的版本:
3. 使用 Virtualenv 安装 Django
安装 Django 框架的方式有多种,本人推荐使用 Virtualenv 虚拟环境安装。因为在以后的开发中,不同的应用可能需要不同的 Python 开发环境,而Virtualenv 可以用来为应用创建一套“隔离”的Python运行环境,而不会干扰到系统中其他的 Python 应用。
安装 Python virtualenv 包:
1
| $ sudo pip install virtualenv
|
注意:如果由于某些不可以描述的原因导致 pip 安装缓慢,可以尝试临时修改源的方法:
可以在使用pip的时候在后面加上-i参数,指定pip源。
例如,对上面的命令指定临时源:
1
| $ sudo pip install virtualenv -i https://pypi.tuna.tsinghua.edu.cn/simple
|
国内的一些源:
根据个人需要,选择合适的目录创建 Python 虚拟环境 my_env。
我这里的选择的目录是: /home/matrix/Workspace/Python/Virtualenv
创建 Python 虚拟环境:
1 2
| $ cd ~/Workspace/Python/Virtualenv $ virtualenv myenv
|
激活虚拟环境:
1 2
| $ cd my_env $ source bin/active
|
安装 2.2 LTS 版本的 Django 框架:
1
| $ django-admin --version
|
检查 Django 版本:
1
| $ django-admin --version
|
看到以上的版本号输出,说明已经安装成功了。
若想切换为正常的用户环境,可以使用以下的命令:
快速构建简单的 Blog
按第一部分的介绍搭建好 Django 的开发环境后,接下来将介绍如何快速地创建一个 Blog。
1. 创建名为 my_site 的工程项目
使用 django-admin.py 工具创建工程项目:
1
| $ django-admin.py startproject mysite
|
项目的文件结构如下:
- manage.py : Django 项目里面的工具,通过它可以调用 Django Shell 和数据库等。
- settings.py : 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
- urls.py : 项目的 URL 声明,就像你网站的 “目录” ,负责把 URL 模式映射到应用程序。
- init.py : 一个空文件,告知 Python 当前目录应被认为是一个 Python 包。
- wsgi.py : 作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。
2. 运行开发服务器
切换到工程项目里,执行以下指令运行开发服务器:
1
| $ python manage.py runserver
|
然后打开浏览器,在地址栏输入 127.0.0.1:8000
访问站点。
3. 创建 Blog 应用
在 mysite 目录下,使用 manage.py 创建 blog 应用:
1
| $ python manage.py startapp blog
|
blog 应用的文件结构如下:
4. 设计 Blog应用的 Model
在 blog 目录下的 models.py 是 blog 应用的核心文件之一,是定义 blog 数据结构的地方。
用编辑器打开models.py ,新添加BlogPost类,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| from django.db import models
from django.contrib.auth.models import User
STATUS = ( (0,"Draft"), (1,"Publish") )
class Post(models.Model): title = models.CharField(max_length=200, unique=True) slug = models.SlugField(max_length=200, unique=True) author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts') updated_on = models.DateTimeField(auto_now= True) content = models.TextField() created_on = models.DateTimeField(auto_now_add=True) status = models.IntegerField(choices=STATUS, default=0)
class Meta: ordering = ['-created_on']
def __str__(self): return self.title
|
5.设置数据库
Dajango支持主流的数据库服务器(MySQL,PostgreSQL,Oracle和MSSQL),但本项目使用SQLite,这里之需要通过一条简单的命令可以创建SQLite数据库。
在终端 切换到工程主目录mysite/下,执行如下命令:
1 2
| $ python manage.py makemigrations $ python manage.py migrate
|
运行上述的数据迁移指令后,会生成框架自带的相关数据表和 我们自己创建的 Post 数据表。
创建后台管理员账号:
1
| $ python manage.py createsuperuser
|
在浏览器地址栏输入:127.0.0.1:8000/admin
成功登录有就会见到后台管理界面:
6. 把 Post 模型添加到管理员后台
打开 blog/admin.py 文件,注册 BlogPost 模型:
1 2 3 4 5 6
| from django.contrib import admin
from .models import Post
admin.site.register(Post)
|
保存文件,刷新管理员后台页面:
7.添加文章
点击 Posts右侧的Add 按钮,添加文章。
修改 blog/admin.py 文件,为它添加一个admin.ModelAdmin的子类BlogPostAdmin.以列表形式显示BlogPost的标题和时间,可以让admin的BlogPost界面更加美观。
原来的代码:
1 2 3 4 5 6
| from django.contrib import admin
from .models import Post
admin.site.register(Post)
|
修改后的代码:
1 2 3 4 5 6 7 8 9 10
| from django.contrib import admin from .models import Post
class PostAdmin(admin.ModelAdmin): list_display = ('title', 'slug', 'status','created_on') list_filter = ("status",) search_fields = ['title', 'content'] prepopulated_fields = {'slug': ('title',)} admin.site.register(Post, PostAdmin)
|
刷新页面后,可看到效果:
8. 创建 Blog 的视图
从Django的角度看,一个页面具有三个典型的组件:
- 一个模板(template):模板负责把传递进来的信息显示出来。
- 一个视图(viw):视图负责从数据库获取需要显示的信息。
- 一个URL模式:它负责把收到的请求和你的试图函数匹配,有时候也会向视图传递一些参数。
编辑视图:
打开 blog/views.y ,并编辑:
1 2 3 4 5 6 7 8 9 10
| from django.views import generic from .models import Post
class PostList(generic.ListView): queryset = Post.objects.filter(status=1).order_by('-created_on') template_name = 'index.html'
class PostDetail(generic.DetailView): model = Post template_name = 'post_detail.html'
|
为视图添加 URL模式
在 blog 应用目录创建 urls.py 文件,然后编辑它:
blog/urls.py
1 2 3 4 5 6 7
| from . import views from django.urls import path
urlpatterns = [ path('', views.PostList.as_view(), name='home'), path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'), ]
|
把 blog 应用的 URLS 添加到项目的 urls.py 文件中:
mysite/urls.py
1 2 3 4 5 6 7
| from django.contrib import admin from django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('', include('blog.urls')), ]
|
9. 为视图创建模版
在工程目录创建 templates 文件夹:
然后打开 mysite/settings.py 文件,在 BASE_DIR 底下 添加模版路径:
1
| TEMPLATES_DIRS = os.path.join(BASE_DIR,'templates')
|
即, 在 setting.py 中,找到 TEMPLATES 位置,编辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [TEMPLATES_DIR], '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 文件夹里面,创建 base.html 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| <!DOCTYPE html> <html> <head> <title>Matrix Tech</title>
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet"> <meta name="google" content="notranslate" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" /> </head>
<body> <style> body { font-family: "Roboto", sans-serif; font-size: 17px; background-color: }
.shadow{ box-shadow: 0 4px 2px -2px rgba(0,0,0,0.1); } .btn-danger { color: background-color: border-color: } .masthead { background: height: auto; padding-bottom: 15px; box-shadow: 0 16px 48px padding-top: 10px; } </style>
<!-- Navigation --> <nav class="navbar navbar-expand-lg navbar-light bg-light shadow" id="mainNav"> <div class="container-fluid"> <a class="navbar-brand" href="{% url 'home' %}" >Matrix Tech</a> <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation" > <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarResponsive"> <ul class="navbar-nav ml-auto"> <li class="nav-item text-black"> <a class="nav-link text-black font-weight-bold" href="#" >About</a > </li> <li class="nav-item text-black"> <a class="nav-link text-black font-weight-bold" href="#" >Policy</a > </li> <li class="nav-item text-black"> <a class="nav-link text-black font-weight-bold" href="#" >Contact</a > </li> </ul> </div> </div> </div> </nav>
{% block content %} <!-- Content Goes here --> {% endblock content %} <!-- Footer --> <footer class="py-3 bg-grey"> <p class="m-0 text-dark text-center ">Copyright © Matrix Tech</p> </footer> </body> </html>
|
在 templates 文件夹里面,创建 index.html 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| {% extends "base.html" %} {% block content %} <style> body { font-family: "Roboto", sans-serif; font-size: 18px; background-color: }
.head_text{ color: white; } .card{ box-shadow: 0 16px 48px } </style>
<header class="masthead" > <div class="overlay"></div> <div class="container"> <div class="row"> <div class=" col-md-8 col-md-10 mx-auto"> <div class="site-heading"> <h3 class=" site-heading my-4 mt-3 text-white"> 欢迎访问我的博客 </h3> <p class="text-light">Write the Code. Change the World.   </p> </div> </div> </div> </div> </div> </header> <div class="container"> <div class="row"> <!-- Blog Entries Column --> <div class="col-md-8 mt-3 left"> {% for post in post_list %} <div class="card mb-4" > <div class="card-body"> <h2 class="card-title">{{ post.title }}</h2> <p class="card-text text-muted h6">{{ post.author }} | {{ post.created_on}} </p>
<p class="card-text">{{post.content|slice:":200" }}</p> <a href="{% url 'post_detail' post.slug %}" class="btn btn-primary">Read More →</a> </div> </div> {% endfor %} </div> {% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %} </div> </div> {%endblock%}
|
在 templates 文件夹里面,创建 sidebar.html 文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| {% block sidebar %}
<style> .card{ box-shadow: 0 16px 48px } </style>
<!-- Sidebar Widgets Column --> <div class="col-md-4 float-right "> <div class="card my-4"> <h5 class="card-header">About Us</h5> <div class="card-body"> <p class="card-text"> Hi, 我是 Matrix, 一名全栈工程师, 熟悉前后端开发和运维各个环节.</p> <a href="" class="btn btn-danger">Know more!</a> </div> </div> </div>
{% endblock sidebar %}
|
在浏览器访问 http://127.0.0.1:8000/
创建 post_detail.html 文件
mysite/templates/post_detail.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| {% extends 'base.html' %} {% block content %}
<div class="container"> <div class="row"> <div class="col-md-8 card mb-4 mt-3 left top"> <div class="card-body"> <h1>{% block title %} {{ object.title }} {% endblock title %}</h1> <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p> <p class="card-text ">{{ object.content | safe }}</p> </div> </div> {% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %} </div> </div>
{% endblock content %}
|
点击页面文章摘要下的 Read More 可以访问 Post 的详细内容:
后记
此教程可以作为 Django 入门练习,通过教程学可以会在 Ubuntu 上搭建 Django 开发环境,以及如何使用 Django 框架。教程是采用『线索性』书写方式,跟着教程一步步练习最终就会搭建出一個简易博客。由于此教程只是展示如何简单入门,所以很多开发细节被忽略,如果希望进一步了解 Django 的使用可以参阅 Django 官方手册。
项目源代码地址: https://github.com/matrixtechxyz/Django_Mysite
Comments