Django也属于面先对象的编程方式,因此以对象的形式承载数据及与数据库进行传输。
在blog应用的models.py中编写数据模型,数据模型都必须继承models.Model,模型的属性也以系统规定的类型进行定义,如models.CharField等。参照追梦人物老师的教程,我们定义了博客及其分类、标签三个数据模型,如下。
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
class Category(models.Model):
"""
blog的分类的模型
"""
name = models.CharField(max_length=100) # 分类名,字符类型的属性必须指明长度
class Tag(models.Model):
"""
blog的标签的模型
"""
name = models.CharField(max_length=100) # 标签名
class Post(models.Model):
"""
博客数据模型
"""
title = models.CharField(max_length=70, primary_key=True) # 文章标题
body = models.TextField() # 文章正文,数据量太大用textfield
create_time = models.DateTimeField() # 创建时间 datetimefield类型数据
modified_time = models.DateTimeField() # 最后修改时间
abstract = models.CharField(max_length=500, blank=True) # 摘要 blank=True表示可以为空
"""
category表示文章的分类,文章与分类属于一对多的关系,即一篇文章只能有一个分类,而一个分类可以包含多篇文章。
此时分类对于文章来说是唯一的,分类就是文章的外键(相反却不行),表明一篇文章必须有且只有一个分类。
on_delete=models.CASCADE为级联删除,表明当外键被删除后,当前对象也要被删除(属于该分类的所有文章都被删除)。
"""
category = models.ForeignKey(Category, on_delete=models.CASCADE)
"""
tag表示文章的标签,文章与标签属于多对多的关系,即一篇文章可以有任意多个标签,而一个标签也可以包含多篇文章。
标签属性不是必须的,所以blank=True
"""
tag = models.ManyToManyField(Tag, blank=True)
"""
User来自系统定义的模型
"""
author = models.ForeignKey(User, on_delete=models.CASCADE)
如上所示,在post模型中涉及两类模型间的关系:一对多和多对多。详细解释见代码注释。
此外还有一对一的关系。
identity = models.OneToOneField(User,on_delete=models.CASCADE, primary_key=True)
其中primary_key显示指定主键。如果不指定,Django会有默认主键id,且每个实例增1。
Django项目在settings.py文件的DATABASE字段下进行数据库的配置,默认为sqlite3
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3'
}
}
本文使用postgresSQ作为数据库。
对于Django项目而言由于具有对象关系映射机制(ORM),使用何种数据库在项目中的操作都差别不大。
postgres官网下载windows版本的安装包,安装过程中会提升设置用户及密码。
开启数据库服务
pg_ctl start -D ..\data
官网下载paAdmin4windows版本安装包并安装好之后,连接到postgresSQ服务器。
在Django项目中使用postgresSQ数据库需要第三方库psycopg2的支持,在虚拟环境中进行安装(虚拟环境相关详情请见Django 学习之旅(一)新建项目):
Django项目中配置postgresS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'blog', # 选择的数据库名
'USER': 'postgres', # 用户
'PASSWORD': '*****', # 用户密码
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
将blog应用在INSTALLED_APPS字段中进行注册
在终端执行数据迁移
注意:执行数据迁移前要先创建对象的数据库,确保对应的数据库已存在!
python manage.py makemigrations
随后执行
python manage.py migrate
使用paAdmin4查看数据库情况
我们的数据模型在数据库按照"应用_模型"的形式创建成功,其中blog_post_tag是因为post与tag的多对多关系额外使用一张表进行管理。
除了我们的blog应用所创建的4张数据表外,系统自带的其他应用(如auth)也有对象的数据表。
在终端输入
python manage.py shell
开启交互式命令行。
添加Category数据和Tag数据
from blog.models import Category,Tag,Post
>>> c=Category(name='category test')
>>> c.save()
>>> t=Tag(name='tag test')
>>> t.save()
在终端输入python manage.py createsuperuser创建User(系统用户),用以blog的作者。
使用创建的user创建Post对象
from django.utils import timezone
from django.contrib.auth.models import User
user = User.objects.get(username='admin')
>>> c = Category.objects.get(name='category test')
>>> p = Post(title='title test', body='body test', created_time=timezone.now(), modified_time=timezone.now(), category=c, author=user)
>>> p.save()
使用 “模型.objects.all()” 方法可以查询所有数据,“模型.objects.get(查询条件)”查询满足条件的一个对象。
但该方法默认返回的是结果集的可迭代对象:
Category.objects.all()
>>]>
对模型数据增加 "__str__"方法,设置查询结果显示哪些数据
class Category(models.Model):
"""
blog的分类的模型
"""
name = models.CharField(max_length=100) # 分类名,字符类型的属性必须指明长度
def __str__(self): # 配置跌打对象的显示对象名
return self.name
查询结果:
>>> Category.objects.all()
]>
先通过get()方法获得待改对象,括号里是筛选条件。然后对其修改,最后保存
>>> c = Category.objects.get(name='category test')
>>> c.name = 'category test new'
>>> c.save()
同样使用get方法获得待删除对象,使用 “对象.delete()”方法删除对象。
>>> p = Post.objects.get(title='title test')
>>> p
>>> p.delete()
(1, {'blog.Post': 1})
>>> Post.objects.all()