一、修改语言时区及数据库
1. 修改语言、时区
更改setting.py
文件中内容:
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
更改为:
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
2. 修改默认数据库
默认生成的数据库是:sqlite3,我使用最主流的关系型数据库MySQL,在系统中安装好MySQL和Navicat Premium,,新建一个数据库:
更改setting.py
数据:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
更改为:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_blog', #新建的数据库名
'USER':'root', #用户名
'PASSWORD':'******', #密码
'HOST':'127.0.0.1', #本机地址
'PORT':'3306', #端口
}
}
如果Python并没有与mysql连接上,在虚拟环境中,安装mysqlclient
:
pip install mysqlclient
二、建立第一个app
1.建立app
Django中的一个app就是一个小的项目,通过startapp
命令来创建:
python manage.py startapp blog #不要与根目录重名
这样就可以创建出一个根目录下的名为blog
的app了。然后,我们将其加入到setting.py
中的INSTALLED_APPS
中,如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
2.迁移数据库
依次执行下列命令:
python manage.py makemigrations
python manage.py migrate
当我们执行了 makemigrations
后,Django 在blog
应用的 migrations\
目录下生成了一个0001_initial.py
文件,这个文件是 Django 用来记录我们对模型做了哪些修改的文件。
不过此时还只是告诉了 Django 我们做了哪些改变,为了让 Django 真正地为我们创建数据库表,接下来又执行了migrate
命令。Django 通过检测应用中migrations\
目录下的文件,得知我们对数据库做了哪些操作,然后它把这些操作翻译成数据库操作语言,从而把这些操作作用于真正的数据库。
经过这两项操作后,我们打开navicat
中的django_blog
数据库表单,发现多了如下表单,这些表单为Django 自身还内置的很多应用,这些应用本身也是需要存储数据的。
在Pycharm中连接Mysql要是报[08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up.,则检查驱动版本
3. 网站数据库设计思想
从网站的功能上分析,看看这个博客网站需要建立哪些表,每个表中都需要什么字段。
首先,最主要的是我们的文章表,名字可以直接叫做Blog,这个表中,肯定要包括以下几点:文章的标题、文章的内容、文章的发表时间、文章的修改时间、文章的分类、文章的点击量。当然,一般情况下还要有文章的作者,因为我们整个网站都是只有我们自己一个人,也就是不包含其它用户,因此作者这里就可以不写了。针对文章的分类,一篇博客只能有一个分类,但是可以有多个标签,比如我现在写的这篇博客,可以分类到django 下,但是它可以有多个标签:django、博客、数据库、开发……
考虑到每一篇博客都只能有一个分类,而一个分类下是可以包含很多博客的,因此分类与博客是一对多
的关系,此时应当使用外键来进行关联。而一篇博客可以有多个标签, 每个标签也可以包含多个博客,因此,标签与博客是多对多
的关系。关于一对多与多对多的知识话题,查看django文档与相关资料。
因此,通过上述分析,我们可以确定出三个数据表,文章(Blog)、分类(Category)与标签(Tag)
。下面在blog
目录下的models.py中创建这三个表,由于Blog表包含外键与多对多关系,因此首先应当建立另外两个表:
分类(Category)表的创建:
class Category(models.Model):
"""
文章分类
"""
name = models.CharField(verbose_name='文章类别', max_length=20)
class Meta:
verbose_name = '文章类别' # verbose_name:人类可直观读取的名称
verbose_name_plural = verbose_name # 单复数同型
def __str__(self):
return self.name
verbose_name:人类可直观读取的名称
verbose_name_plural :指定verbose_name的复数形式
Meta:元数据
这里我们只需要包含一个字段name就行了。
标签(Tag)的创建:
class Tag(models.Model):
"""
文章标签
"""
name = models.CharField(verbose_name='文章标签', max_length=20)
class Meta:
verbose_name = '文章标签'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
文章(Blog)表的创建:
from django.utils import timezone
class Blog:
"""
文章
"""
title = models.CharField(verbose_name='标题', max_length=100)
content = models.TextField(verbose_name='正文', default='')
create_time = models.DateTimeField(
verbose_name='创建时间', default=timezone.now()) #now不带括号会怎样?
modify_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)
click_nums = models.IntegerField(verbose_name='点击量', default=0)
category = models.ForeignKey(Category, verbose_name='文章类别',on_delete=models.CASCADE) #on_delete不能掉!
tag = models.ManyToManyField(Tag, verbose_name='文章标签')
class Meta:
verbose_name = '我的文章'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
关于博客表有以下几点需要注意的:
- 标题应当限定长度,我们设定最大值为100
- 内容不用限定长度,因此用的是TextField字段
- 创建时间按理说应该是不能修改的,应该设定成auto_now_add=True,这样在添加对象时,时间是默认成现在的,且不能修改,可以说你在后台就看不到它。但因为我们现在是开发环境,之后还要从后台添加数据进行测试,如果时间都一样的话,很多功能体现不出来,因此现在设定成可以更改的样式,真正部署时,建议改成auto_now_add=True。
- 修改时间直接设定成,auto_now=True,在你修改时,会自动变成当前时间。
- 关于ForeignKey与ManyToManyField,请自行查看相关文档资料
on_deleta
不要忘了
原因:
在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错:
TypeError: init() missing 1 required positional argument: ‘on_delete’
举例说明:
user=models.OneToOneField(User)
owner=models.ForeignKey(UserProfile)
需要改成:
user=models.OneToOneField(User,on_delete=models.CASCADE) –在老版本这个参数(models.CASCADE)是默认值
owner=models.ForeignKey(UserProfile,on_delete=models.CASCADE) –在老版本这个参数(models.CASCADE)是默认值
参数说明:
on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值
CASCADE:此值设置,是级联删除。
PROTECT:此值设置,是会报完整性错误。
SET_NULL:此值设置,会把外键设置为null,前提是允许为null。
SET_DEFAULT:此值设置,会把设置为外键的默认值。
SET():此值设置,会调用外面的值,可以是一个函数。
一般情况下使用CASCADE就可以了。
建模完成后,执行:
python manage.py makemigrations
python manage.py migrate
在后续开发过程中,可以随时对其进行变更。当多数据表信息变动时,要执行makemigrations 与 migrate
这样才能使改动生效。
4. 实际设计网站数据库
Django是通过Model操作数据库,不管你数据库的类型是MySql或者Sqlite,Django它自动帮你生成相应数据库类型的SQL语句,所以不需要关注SQL语句和类型,对数据的操作Django帮我们自动完成。只要回写Model就可以了!
Django根据代码中定义的类
来自动生成数据库表
。我们写的类表示数据库的表,如果根据这个类创建的对象是数据库表里的一行数据,对象.id 对象.value是每一行里的数据。
基本的原则如下:
- 每个模型在Django中的存在形式为一个Python类
- 每个模型都是
django.db.models.Model
的子类 - 模型里的每个类代表数据库中的一个表
- 模型的每个字段(属性)代表数据表的某一列
- Django将自动为你生成数据库访问API
一个功能完善的博客中需要存储六种数据结构:文章分类、文章、文章标签、幻灯图、推荐位、友情链接。每种数据一个表。
分类表结构设计:
表名:Category、分类名:name
标签表设计:
表名:Tag、标签名:name
文章表结构设计:
表名:Article、标题:title、摘要:excerpt、分类:category、标签:tags、推荐位、内容:body、创建时间:created_time、作者:user、文章封面图片img
幻灯图表结构设计:
表名:Banner、图片文本text_info、图片img、图片链接link_url、图片状态is_active。
友情链接表结构设计:
表名:Link、链接名name、链接网址linkurl。
各表关系:
- 文章和分类是一对多的关系,
- 文章和标签是多对多的关系,
- 文章和作者是一对多的关系,
- 文章和推荐位是一对多关系(看自己的需求,也可以设计成多对多)。
打开blog/models.py,输入代码:
from django.db import models
# Create your models here.
from django.contrib.auth.models import User
from django.utils import timezone
class Category(models.Model):
"""
文章分类
"""
name = models.CharField(verbose_name='文章类别', max_length=20)
index = models.IntegerField(default=999, verbose_name='分类排序')
class Meta:
verbose_name = '文章类别' # verbose_name:人类可直观读取的名称
verbose_name_plural = verbose_name # 单复数同型
def __str__(self):
return self.name
class Tag(models.Model):
"""
文章标签
"""
name = models.CharField(verbose_name='文章标签', max_length=20)
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:
"""
文章
"""
title = models.CharField(verbose_name='标题', max_length=100)
excerpt = models.TextField(verbose_name='摘要', max_length=200, blank=True)
content = models.TextField(verbose_name='正文', default='')
created_time = models.DateTimeField(
verbose_name='创建时间', default=timezone.now())
modify_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)
click_nums = models.IntegerField(verbose_name='点击量', default=0)
category = models.ForeignKey(
Category,
verbose_name='文章类别',
on_delete=models.DO_NOTHING,
blank=True,
null=True) # 使用外键关联分类表与分类是一对多关系
tag = models.ManyToManyField(
Tag,
verbose_name='文章标签',
blank=True) # 使用外键关联标签表与标签是多对多关系
img = models.ImageField(
verbose_name='文章图片',
upload_to='article_img/%Y/%m/%d/',
blank=True,
null=True)
user = models.ForeignKey(User, verbose_name='作者', on_delete=models.CASCADE)
"""
文章作者,这里User是从django.contrib.auth.models导入的。
这里我们通过 ForeignKey 把文章和 User 关联了起来。
"""
views = models.PositiveIntegerField(verbose_name='阅读量', default=0)
tui = models.ForeignKey(
Tui,
verbose_name='推荐',
on_delete=models.DO_NOTHING,
blank=True,
null=True)
class Meta:
verbose_name = '我的文章'
verbose_name_plural = verbose_name
def __str__(self):
return self.title
class Banner(models.Model):
text_info = models.CharField(verbose_name='标题', max_length=50, default='')
img = models.ImageField(verbose_name='图片轮播', upload_to='banner/')
link_url = models.URLField(verbose_name='图片链接', max_length=100)
is_activate = models.BooleanField(
verbose_name='是否是activate', default=False)
def __str__(self):
return self.text_info
class Meta:
verbose_name = '轮播图'
verbose_name_plural = verbose_name
class Link(models.Model):
name = models.CharField(verbose_name='链接名称', max_length=20)
linkurl = models.URLField(verbose_name='网址', max_length=100)
def __str__(self):
return self.name
class Meta:
verbose_name = '友情链接'
verbose_name_plural = verbose_name
这里面我们多增加了一个img图片封面字段,用于上传文章封面图片的,article_img/为上传目录,%Y/%m/%d/为自动在上传的图片上加上文件上传的时间。
运行:
python manage.py makemigrations
python manage.py migrate
三、创建admin管理后台
Django中一个最强大的部分是自动管理接口,在模型中读取元数据来提供一个强大的、生产就绪的接口,使内容提供者能立即用它向站点中添加内容。
创建管理员
输入:
python manage.py createsuperuser
然后按照提示依次输入用户名、邮箱、密码、确认密码,即可创建出管理员用户。
运行服务:
python manage.py runserver
进入http://127.0.0.1:8000/admin
管理后台
admin配置
登录后台后,我们看到此时的后台只有用户、组和最近动作,并没有我们之前创建的我的博客、博客分类、博客标签这些内容。
我们可以在admin.py
中进行配置,将其在后台展现出来:
发表回复