当我们要开发一个项目的时候,首先需要了解我们项目的具体需求,根据需求类型划分网站功能,并详细了解这些需求的业务流程。然后更具需求和业务流程进行数据库设计。本教程以一个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主要以文章内容为主。所以我们在设计数据库的时候,我们主要以文章信息为核心数据,然后逐步向外扩展相关联的数据信息。
这其中,文章与分类的关系是一对多的关系,什么是一对多?就是一篇文章只能有一个分类,而一个分类里可以有多篇文章。文章与标签的关系是多对多的关系,多对多简单理解就是,一篇文章可以有多个标签,一个标签里同样可以有多篇文章。关于一对多、多对多,大家可以查看这篇文章:多个数据模型间的关系
我们将文章表命名为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为项目保存路径,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安装。
安装成功之后项目目录结构如下图所示:
第一个黑色的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自动会帮我们启动虚拟环境。如下图所示:
这里面有两个地方需要留意:
1、留意项目路径,看这个路径是不是我们项目的路径。
2、留意路径前有没有我们创建的虚拟环境名,之前我们创建的虚拟环境名是myblogvenv,如果显示正确,则说明我们启动正确。如果没有虚拟环境名,则进入项目目录下的myblogvenv\Scripts目录里,在终端输入activate启动虚拟环境,然后再切换到项目根目录里。如果前面的虚拟环境名称不对,则在终端输入deactivate退出虚拟环境,然后按上面的方法启动虚拟环境。
上面都OK了,我们就在终端里依次输入如下命令进行数据库迁移:
python manage.py makemigrationspython manage.py migrate
迁移数据之后,网站目录里自动会创建一个数据库文件db.sqlite3,里面存放着我们的数据。
之后输入下面命令创建管理帐号和密码:
python manage.py createsuperuser
注意:密码不要太简单或者和电子邮件相似,不然Django会有风险提示。
最后,我们输入下面有命令,启动我们的Django项目:
python manage.py runserver #默认使用8000端口python manage.py runserver 8080 #指定启动端口python manage.py runserver 127.0.0.1:9000 #指定IP和端口
提示启动成功,然后我们在浏览器里输入:http://127.0.0.1:8000/
就可以查看到Django默认的欢迎页面!
是不是有一种成就感?这就是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), #+]
留意:代码后面有个#+表示是我新添加的代码。
代码写好之后,启动项目,刷新页面。就可以看到:
OK,自定义欢迎页面成功显示!
之后,我们在浏览器里面访问:http://127.0.0.1:8000/admin 就可以进入Django自带的后台管理。
输入刚才我们创建的帐号与密码,点击登录。
进入到管理后台,这个后台功能十分强大。后面我们会对其进行详细介绍。
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
迁移的时候,会有如下提示:
出现这个原因是因为我们的幻灯图使用到图片字段,我们需要引入图片处理包。提示里也给了我们处理方案,输入如下命令,安装Pillow模块即可:
pip install Pillow
安装成功之后再迁移数据库
数据库迁移成功之后,程序会在blog下的migrations目录里自动生成几个000开头的文件,文件里面记录着数据库迁移记录:
大家可以查看一下。了解迁移的过程。本文就不做过多介绍。
上节我们我们把数据库迁移到数据库里去了,那么现在我们数据库里是个什么样的情况呢?我们点击Pycharm右上角的Database,然后在网站项目里选中我们的数据库文件db.sqlite3,把它拖到Database框里。
然后点击db,就可以查看到我们的网站数据库,我们可以对数据进行增、删、改、查操作。
更多相关方面的操作请查看文章:使用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/
注册之前的后台:
注册之后,启动项目,刷新页面:
多出了之前我们在models里创建的表。我们可以在后台里面对这些表进行增、删、改方面的操作。