当我们要开发一个项目的时候,首先需要了解我们项目的具体需求,根据需求类型划分网站功能,并详细了解这些需求的业务流程。然后更具需求和业务流程进行数据库设计。本教程以一个Blog为例进行介绍,Blog演示站地址如下:http://demo.django.cn/

blog的功能相对比较简单,主要以文章为主。

从功能需求来看,这个Blog的功能分为:网站首页、文章分类、文章内容、幻灯图片、文章推荐、文章排行、热门推荐、文章搜索、友情链接。

1、网站首页:网站首页是整个网站的主界面,也是网站入口界面,里面主要展示Blog的动态信息及Blog功能导。网站动态信息以文章为主,如最新文章、幻灯图片、推荐阅读、文章排行、热门推荐、友情链接等。导航栏主要是将文章的分类的链接展示在首页,方便用户浏览。

2、文章分类,主要展示文章分类信息及链接,方便用户按需查看。文章分类可以在后台添加删除。

3、文章内容,主要展示文章所属分类、文章所属标签、文章内容、作者信息,发布时间信息。可以通过后台增、删、改。

4、幻灯图片,在网站首页,通过图片和文字展示一些重要信息,可以通过后台添加图片、图片描述、图片链接。

5、文章推荐,推荐一些重要的文章,可以在后台进行推荐。

6、文章排行,可根据文章浏览数,按时间段进行查询,然后展示出来。具体可根据自己的需求修改。

7、热门推荐,同样的推荐一些需要推荐的文章,可以在后台按需求或推荐位进行设置。

8、文章搜索,通过关键词搜索文章。

9、友情链接,展示相互链接的网站的名称与链接,可以通过后台添加与删除。

10、单页面,展示网站介绍,作者联系方式等信息,此类信息不经常变动,可以通过后台实现修改,也可以通过修改模板实现。


了解需求之后,就由UI设计师根据网站需求来设计网站页面,然后由前端工程师根据设计好的页面进行切图,实现HTML静态页面,最后由后端根据HTML页面和需求实现数据库构建和网站后台开发。

从设计方面来看,Blog主要分为六个页面,分别是:网站首页、文章分类列表页、文章内容页、搜索列表页、标签列表页、单页面。

1、网站首页,信息聚合的地方,展示多种信息。对应演示站的这个网址:http://demo.django.cn/

2、文章分类列表页,点击分类,进入一个同一分类文章展示的列表页面,对应演示站这个地址:http://demo.django.cn/list-2.html

3、文章内容页,文章内容展示页面,对应演示站这个地址:http://demo.django.cn/show-7.html

4、搜索列表页,通过首页搜索按钮,展示出与搜索 词相关的文章列表。对应地址:http://demo.django.cn/s/?search=%E8%AE%BE%E8%AE%A1

5、标签列表页,展示同一个标签下的所有文章。对应网址:http://demo.django.cn/tag/Python%E6%95%99%E7%A8%8B

6、单页面,展示网站介绍、作者介绍或者联系方式等信息。对应网址:http://demo.django.cn/about/

从网站需求分析及网站功能、页面设计可以知道,我们的Blog主要以文章内容为主。所以我们在设计数据库的时候,我们主要以文章信息为核心数据,然后逐步向外扩展相关联的数据信息。

1111.jpg
2222.jpg

这其中,文章与分类的关系是一对多的关系,什么是一对多?就是一篇文章只能有一个分类,而一个分类里可以有多篇文章。文章与标签的关系是多对多的关系,多对多简单理解就是,一篇文章可以有多个标签,一个标签里同样可以有多篇文章。关于一对多、多对多,大家可以查看这篇文章:多个数据模型间的关系

我们将文章表命名为Article,通过前面的分析得出文章信息表Article的数据库结构如下:

表字段
字段类型
备注
id
int类型,长度为11
主键,由系统自动生成
titleCharField类型,长度为100
文章标题
categoryForeignKey外键,关联文章分类表
tags
ManyToManyField多对多,关联标签列表
bodyTextField文章内容
userForeignKey外键,文章作者关联用户模型,系统自带的
viewsPositiveIntegerField

文章浏览数,正的整数,不能为负

tuiForeignKey

外键,关联推荐位表

created_timeDateTimeField

文章发布时间

从文章表里,我们关联了一个分类表,我们把这个分类表命名为category,category表的数据库结构如下:

表字段字段类型备注id
int类型,长度为11主键,由系统自动生成name
CharField类型,长度为30分类名

文章关联的标签表,我们命名为tag,结构如下:

表字段字段类型备注id
int类型,长度为11主键,由系统自动生成name
CharField类型,长度为30标签名

文章关联的推荐位表,命名为tui,结构如下:

表字段字段类型备注id
int类型,长度为11主键,由系统自动生成name
CharField类型,长度为30标签名

除此之外,我们还有两个独立的表,和文章没有关联的,一个是幻灯图片的表,一个是友情链接的表。

幻灯图表,命名为banner,数据库结构如下:

表字段字段类型备注id
int类型,长度为11主键,由系统自动生成text_infoCharField类型,长度为100标题,图片文本信息
img
ImageField类型
图片类型,保存传图片的路径
link_urlURLField类型
图片链接的URL
is_activeBooleanField布尔类型
有True 和False两个值,意思为是否激活

友情链接表命名为link,结构如下:

表字段字段类型备注id
int类型,长度为11主键,由系统自动生成nameCharField类型,长度为70友情链接的名称
linkurlURLField类型
友情链接的URL

至此,我们的数据库构造大致完成,后期如果还有其它的需求,我们可以在这基础上进行增加或者删除。下面我们就开始进行项目的创建与开发。

我们对需求和数据库都进行分析了之后,我们就开始来创建我们的项目。教程是在windows10操作系统下,用的Python3.6和django2.1.1,开发工具为pycharm。

打开我们的Pycharm,新建一个项目。

1.jpg

说明:

1为项目保存路径,myblog为项目名。

2为选择使用的虚拟环境软件,这里选virtualenv。

3为虚拟环境保存目录,我把它保存在项目里,虚拟环境默认名为env,我系统里有多个项目为了区分出来命名为myblogenv

4为使用的模板语言,我们默认用django模板语言。

5为创建项目的时候建立一个模板文件目录,用来存放模板文件。用CMD命令创建项目的话,模板目录需要自己手动创建。

6为创建一个名为blog的APP应用。同样的用CMD命令创建的话,需要手动通过python manage.py startAPP blog命令来进行创建。更多Django命令,请查看:Django常用命令

点击创建之后,Pycharm自动帮我们完成Django软件下载安装和Django的项目创建。

注意:如果对需要指定Django版本的话,不能直接使用这个方法,这个方法会直接下载最新版本的Django。指定版本的话,请使用CMD通过命令如:pip install django==2.0.1安装。

安装成功之后项目目录结构如下图所示:

2.jpg

第一个黑色的myblog为项目文件夹目录。

blog为APP应用目录,也是我们上面设置第6项才创建的。myblog为项目配置目录,myblogvenv为Pycharm创建的虚拟环境目录,与项目无关,不用理会。

目录里的文件含义如下:

blog                #APP应用名和目录│  admin.py        #对应应用后台管理配置文件。│  APPs.py         #对应应用的配置文件。│  models.py       #数据模块,数据库设计就在此文件中设计。后面重点讲解│  tests.py        #自动化测试模块,可在里面编写测试脚本自动化测试│  views.py        #视图文件,用来执行响应代码的。你在浏览器所见所得都是它处理的。│  __init__.py │ ├─migrations        #数据迁移、移植文目录,记录数据库操作记录,内容自动生成。│  │  __init__.py myblog               #项目配置目录│  __init__.py       #初始化文件,一般情况下不用做任何修改。│  settings.py        #项目配置文件,具体如何配置后面有介绍。│  url.py             #项目URL设置文件,可理解为路由,可以控制你访问去处。│  wsgi.py          #为Python服务器网关接口,是Python与WEB服务器之间的接口。myblogvenv            #Pycharm创建的虚拟环境目录,和项目无关,不需要管它。templates           #项目模板文件目录,用来存放模板文件manage.py     #命令行工具,通过可以与项目与行交互。在终端输入python manege.py help,可以查看功能。

创建项目之后,我们需要对项目进行最基础的配置。这些配置是我们做项目的时候必须要配置的,所以我们先提前配置好。

我们打开myblog目录下的settings.py文件。

一、设置域名访问权限

myblog/settings.py ALLOWED_HOSTS = []      #修改前ALLOWED_HOSTS = ['*']   #修改后,表示任何域名都能访问。如果指定域名的话,在''里放入指定的域名即可

二、设置TEMPLATES里的'DIRS',添加模板目录templates的路径,后面我们做网站模板的时候用得着。

myblog/settings.py#修改前'DIRS': []#修改后'DIRS': [os.path.join(BASE_DIR, 'templates')] 注:使用pycharm创建的话会自动添加

三、找到DATABASES设置网站数据库类型。这里我们使用默认的sqlite3。如果需要使用Mysql请查看文章:Django如何使用Mysql数据库,其它数据库请查看官方文档。官方文档,后期上线部署的话,也可以进行数据库与数据库之间的数据转换。具体可查看:如何把SQLite数据库转换为Mysql数据库 

四、在INSTALLED_APPS添加APP应用名称。

myblog/settings.py INSTALLED_APPS = [     'django.contrib.admin',     ....     'blog.APPs.BlogConfig',#注册APP应用]#使用pycharm创建的话,这里自动添加了,如果是终端命令创建的话,需要手动添加应用名称如'blog',

五、修改项目语言和时区

myblog/settings.py#修改前为英文LANGUAGE_CODE = 'en-us'#修改后LANGUAGE_CODE = 'zh-hans' #语言修改为中文#时区,修改前TIME_ZONE = 'UTC'#修改后TIME_ZONE = 'Asia/Shanghai' #

六、在项目根目录里创建static和media,两个目录。static用来存放模板CSS、JS、图片等静态资源,media用来存放上传的文件,后面我们在讲解数据库创建的时候有说明。

settings里找到STATIC_URL,然后在后面一行加上如下代码。

myblog/settings.py#设置静态文件目录和名称STATIC_URL = '/static/'#加入下面代码#这个是设置静态文件夹目录的路径STATICFILES_DIRS = (     os.path.join(BASE_DIR, 'static'), )#设置文件上传路径,图片上传、文件上传都会存放在此目录里MEDIA_URL = '/media/'MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

基本配置完成,更多关于配置文件的介绍,请查看文章:全局配置settings详解

基础配置做好了之后,我们就可以先迁移数据到数据库,然后启动我们的项目,感受Django的魅力。

在Pycharm左下角底部的Terminal,会弹出Terminal终端窗口,Pycharm自动会帮我们启动虚拟环境。如下图所示:

3.jpg

这里面有两个地方需要留意:

1、留意项目路径,看这个路径是不是我们项目的路径。

2、留意路径前有没有我们创建的虚拟环境名,之前我们创建的虚拟环境名是myblogvenv,如果显示正确,则说明我们启动正确。如果没有虚拟环境名,则进入项目目录下的myblogvenv\Scripts目录里,在终端输入activate启动虚拟环境,然后再切换到项目根目录里。如果前面的虚拟环境名称不对,则在终端输入deactivate退出虚拟环境,然后按上面的方法启动虚拟环境。

上面都OK了,我们就在终端里依次输入如下命令进行数据库迁移:

python manage.py makemigrationspython manage.py migrate

4.jpg

迁移数据之后,网站目录里自动会创建一个数据库文件db.sqlite3,里面存放着我们的数据。

14.jpg

之后输入下面命令创建管理帐号和密码:

python manage.py createsuperuser

5.jpg

注意:密码不要太简单或者和电子邮件相似,不然Django会有风险提示。

最后,我们输入下面有命令,启动我们的Django项目:

python manage.py runserver #默认使用8000端口python manage.py runserver 8080 #指定启动端口python manage.py runserver 127.0.0.1:9000 #指定IP和端口

6.jpg

提示启动成功,然后我们在浏览器里输入:http://127.0.0.1:8000/

就可以查看到Django默认的欢迎页面!

7.jpg

是不是有一种成就感?这就是Django的强大之处。几个命令就可以实现一个网站创建。自己动手试试吧。

关于更多的Django命令,大家可以查看文章:Django常用命令

有的朋友觉得这还是不过瘾,说这个欢迎页面是Django自带的,我们能自己做一个欢迎页面么?答案是肯定的。

首先,打开打开bolg目录下的views.py文件,在里面输入:

myblog/blog/views.pyfrom django.http import HttpResponsedef hello(request):    return HttpResponse('欢迎使用Django!')

再打开myblog目录下的urls.py文件,在文件里添加两行代码:

myblog/myblog/urls.pyfrom django.contrib import adminfrom django.urls import pathfrom blog import views         #+ urlpatterns = [     path('admin/', admin.site.urls),     path('', views.hello),   #+]

留意:代码后面有个#+表示是我新添加的代码。

代码写好之后,启动项目,刷新页面。就可以看到:

8.jpg

OK,自定义欢迎页面成功显示!

之后,我们在浏览器里面访问:http://127.0.0.1:8000/admin  就可以进入Django自带的后台管理。

9.jpg

输入刚才我们创建的帐号与密码,点击登录。

10.jpg

进入到管理后台,这个后台功能十分强大。后面我们会对其进行详细介绍。

Django是通过Model操作数据库,不管你数据库的类型是MySql或者Sqlite,Django它自动帮你生成相应数据库类型的SQL语句,所以不需要关注SQL语句和类型,对数据的操作Django帮我们自动完成。只要回写Model就可以了!

django根据代码中定义的类来自动生成数据库表。我们写的类表示数据库的表,如果根据这个类创建的对象是数据库表里的一行数据,对象.id 对象.value是每一行里的数据。

基本的原则如下:
每个模型在Django中的存在形式为一个Python类
每个模型都是django.db.models.Model的子类
模型里的每个类代表数据库中的一个表
模型的每个字段(属性)代表数据表的某一列
Django将自动为你生成数据库访问API

之前我们在前面的数据库设计分析文章里已经分析过数据库的结构。完成博客,我们需要存储六种数据:文章分类、文章、文章标签、幻灯图、推荐位、友情链接。每种数据一个表。

分类表结构设计

表名:Category、分类名:name

标签表设计:

表名:Tag、标签名:name

文章表结构设计:

幻灯图表结构设计:

表名:Banner、图片文本text_info、图片img、图片链接link_url、图片状态is_active。

推荐位表结构设计:

表名:Tui、推荐位名name。

友情链接表结构设计:

表名:Link、链接名name、链接网址linkurl。

其中:

文章和分类是一对多的关系,文章和标签是多对多的关系,文章和作者是一对多的关系,文章和推荐位是一对多关系(看自己的需求,也可以设计成多对多)。

打开blog/models.py,输入代码:

from django.db import modelsfrom django.contrib.auth.models import User #导入Django自带用户模块# 文章分类class Category(models.Model):    name = models.CharField('博客分类', max_length=100)     index = models.IntegerField(default=999, verbose_name='分类排序')     class Meta:        verbose_name = '博客分类'        verbose_name_plural = verbose_name     def __str__(self):        return self.name#文章标签class Tag(models.Model):    name = models.CharField('文章标签',max_length=100)     class Meta:        verbose_name = '文章标签'        verbose_name_plural = verbose_name     def __str__(self):        return self.name#推荐位class Tui(models.Model):    name = models.CharField('推荐位',max_length=100)     class Meta:        verbose_name = '推荐位'        verbose_name_plural = verbose_name     def __str__(self):        return self.name#文章class Article(models.Model):    title = models.CharField('标题', max_length=70)     excerpt = models.TextField('摘要', max_length=200, blank=True)     category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, verbose_name='分类', blank=True, null=True)      #使用外键关联分类表与分类是一对多关系    tags = models.ManyToManyField(Tag,verbose_name='标签', blank=True)     #使用外键关联标签表与标签是多对多关系    img = models.ImageField(upload_to='article_img/%Y/%m/%d/', verbose_name='文章图片', blank=True, null=True)      body = models.TextField()     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='作者')      """      文章作者,这里User是从django.contrib.auth.models导入的。      这里我们通过 ForeignKey 把文章和 User 关联了起来。      """    views = models.PositiveIntegerField('阅读量', default=0)     tui = models.ForeignKey(Tui, on_delete=models.DO_NOTHING, verbose_name='推荐位', blank=True, null=True)          created_time = models.DateTimeField('发布时间', auto_now_add=True)     modified_time = models.DateTimeField('修改时间', auto_now=True)     class Meta:        verbose_name = '文章'        verbose_name_plural = '文章'    def __str__(self):        return self.title#Bannerclass Banner(models.Model):    text_info = models.CharField('标题', max_length=50, default='')     img = models.ImageField('轮播图', upload_to='banner/')     link_url = models.URLField('图片链接', max_length=100)     is_active = models.BooleanField('是否是active', default=False)     def __str__(self):        return self.text_info     class Meta:        verbose_name = '轮播图'        verbose_name_plural = '轮播图'#友情链接class Link(models.Model):    name = models.CharField('链接名称', max_length=20)     linkurl = models.URLField('网址',max_length=100)     def __str__(self):        return self.name     class Meta:        verbose_name = '友情链接'        verbose_name_plural = '友情链接'

这里面我们多增加了一个img图片封面字段,用于上传文章封面图片的,article_img/为上传目录,%Y/%m/%d/为自动在上传的图片上加上文件上传的时间。

里面的模型字段与模型元数据Meta选项详解我在这里就不做过多介绍,更多请点击文章数据模型字段及属性详解和模型元数据Meta选项详解了解。

我们已经编写了博客数据库模型的代码,但那还只是 Python 代码而已,Django 还没有把它翻译成数据库语言,因此实际上这些数据库表还没有真正的在数据库中创建。我们需要进行数据库迁移。

在迁移之前,我们先需要设置数据库,如果我们使用默认的数据库的话,就不需要设置,Django默认使用

sqlite3数据库,如果我们想使用Mysql数据库的话,则需要我们单独配置。我们打开settings.py文件,找到DATABASES,然后把它修改成如下代码:

############修改成mysql如下: DATABASES = {     'default': {         'ENGINE': 'django.db.backends.mysql',         'NAME': 'test',    #你的数据库名称        'USER': 'root',   #你的数据库用户名        'PASSWORD': '445813', #你的数据库密码        'HOST': '', #你的数据库主机,留空默认为localhost        'PORT': '3306', #你的数据库端口    }}#由于mysql默认引擎为MySQLdb,在__init__.py文件中添加下面代码#在python3中须替换为pymysql,可在主配置文件(和项目同名的文件下,不是APP配置文件)中增加如下代码#import pymysql#pymysql.install_as_MySQLdb()#如果找不到pymysql板块,则通过pip install pymysql进行安装。

更多关于Django数据库的配置,请查看官方文档:数据库设置

数据库设置好之后,我们就依次输入下面的命令进行数据库迁移:

python manage.py makemigrationspython manage.py migrate

迁移的时候,会有如下提示:

11.jpg

出现这个原因是因为我们的幻灯图使用到图片字段,我们需要引入图片处理包。提示里也给了我们处理方案,输入如下命令,安装Pillow模块即可:

pip install Pillow

12.jpg

安装成功之后再迁移数据库

13.jpg

数据库迁移成功之后,程序会在blog下的migrations目录里自动生成几个000开头的文件,文件里面记录着数据库迁移记录:

1.jpg

大家可以查看一下。了解迁移的过程。本文就不做过多介绍。

上节我们我们把数据库迁移到数据库里去了,那么现在我们数据库里是个什么样的情况呢?我们点击Pycharm右上角的Database,然后在网站项目里选中我们的数据库文件db.sqlite3,把它拖到Database框里。

15.jpg

然后点击db,就可以查看到我们的网站数据库,我们可以对数据进行增、删、改、查操作。

16.jpg

更多相关方面的操作请查看文章:使用Pycharm里的Database对数据库进行可视化操作

Pycharm Batabase限制非常大,下面我们介绍如何使用Django自带的admin管理网站数据。django的admin后台管理它可以让我们快速便捷管理数据,我们可以在各个APP目录下的admin.py文件中对其进行控制。想要对APP应用进行管理,最基本的前提是要先在settings里对其进行注册,就是在INSTALLED_APPS里把APP名添加进去,我们在前面的文章基础配置有提到过。

注册APP应用之后,我们想要在admin后台里对数据库表进行操作,我们还得在应用APP下的admin.py文件里对数据库表先进行注册。我们的APP应用是blog,所以我们需要在blog/admin.py文件里进行注册:

blog/admin.pyfrom django.contrib import adminfrom .models import Banner, Category, Tag, Tui, Article, Link #导入需要管理的数据库表@admin.register(Article)class ArticleAdmin(admin.ModelAdmin):    list_display = ('id', 'category', 'title', 'tui', 'user', 'views', 'created_time')     # 文章列表里显示想要显示的字段    list_per_page = 50    # 满50条数据就自动分页    ordering = ('-created_time',)     #后台数据列表排序方式    list_display_links = ('id', 'title')     # 设置哪些字段可以点击进入编辑界面@admin.register(Banner)class BannerAdmin(admin.ModelAdmin):    list_display = ('id', 'text_info', 'img', 'link_url', 'is_active')@admin.register(Category)class CategoryAdmin(admin.ModelAdmin):    list_display = ('id', 'name', 'index')@admin.register(Tag)class TagAdmin(admin.ModelAdmin):    list_display = ('id', 'name')@admin.register(Tui)class TuiAdmin(admin.ModelAdmin):    list_display = ('id', 'name')@admin.register(Link)class LinkAdmin(admin.ModelAdmin):    list_display = ('id', 'name','linkurl')

关于admin定制和数据库表注册管理方法,在文章定制Admin管理后台有详细介绍。

登录管理后台http://127.0.0.1:8000/admin/

注册之前的后台:

17.jpg

注册之后,启动项目,刷新页面:

18.jpg

多出了之前我们在models里创建的表。我们可以在后台里面对这些表进行增、删、改方面的操作。