理想国Django ORM入门教程

01.创建项目

django-admin startproject django_model_study
cd django_model_study
python manage.py startapp index

配置:注册app

INSTALLED_APPS = [
    ...
    'index.apps.IndexConfig'
]

运行

python manage.py runserver

02.编写模型

index/models.py

from django.db import models

class Article(models.Model):
    #ID
    # 博客标题
    # 属性 即 字段
    title = models.CharField(verbose_name='标题', max_length=128)
    #博客简介
    info = models.TextField(verbose_name="简介")
    #作者头像
    avatar = models.CharField(verbose_name="头像", max_length=128)
    #作者名称
    name = models.CharField(verbose_name="名称", max_length=24)
    #点赞数量
    good_num = models.IntegerField(verbose_name="点赞数量")
    #阅读数量
    view_num = models.IntegerField(verbose_name="阅读数量")
    #评论数量
    comment_num = models.IntegerField(verbose_name="评论数量")
    #文章内容
    content = models.TextField(verbose_name="文章内容")
    #创建时间
    create_time = models.CharField(verbose_name="创建时间", max_length=128)
    #更新时间
    update_time = models.CharField(verbose_name="跟下时间", max_length=128)

03.迁移数据库

python manage.py makemigrations
python manage.py migrate

04.基本增删改查

进入shell环境

python manage.py shell

导入模型

from index.models import Article

查看所有文章

Article.objects.all()

添加文章

  • 方法1:对象.save()
# 第一步:创建对象
article = Article()

# 第二步:给对象的属性赋值
# 博客标题
article.title = '这是我的第一篇博客'
# 博客简介
article.info = '我很开心,我终于会使用Django ORM框架存储数据了。。。'
# 作者头像
article.avatar = 'http://xxx.com/avatar/default.png'
# 作者名称
article.name = '张大鹏'
# 点赞数量
article.good_num = 100
# 阅读数量
article.view_num = 3300
# 评论数量
article.comment_num = 20
# 文章内容
article.content = '这是博客的文章内容。有很多很多很多很多的描述。。。。'
# 创建时间
article.create_time = '2020年12月10日 13:11:28'
# 更新时间
article.update_time = '2020年12月18日 18:11:28'

第三步:调用save()方法
article.save()
  • 方法2:模型名.objects.create(给属性列表赋值)
Article.objects.create(
    title = '这是我的第二篇博客',
    info = '我还是很开心',
    avatar = 'http://xxx.com/avatar/default.png',
    name = '张大鹏',
    good_num = 100,
    view_num = 3300,
    comment_num = 20,
    content = '这是博客的文章内容。有很多很多很多很多的描述。。。。',
    create_time = '2020年12月10日 13:11:28',
    update_time = '2020年12月18日 18:11:28'
)

查看文章

  • 根据指定的属性获取
Article.objects.get(id=1)
Article.objects.get(title='这是我的第二篇博客')

删除文章

  • 先找到文章
  • 再调用delete()方法
Article.objects.get(id=1).delete()
Article.objects.get(title='这是我的第二篇博客').delete()

修改文章

  • 先找到文章
  • 再修改属性
  • 再保存
Article.objects.create(
    title = '这是我的第三篇博客',
    info = '我还是很开心',
    avatar = 'http://xxx.com/avatar/default.png',
    name = '张大鹏',
    good_num = 100,
    view_num = 3300,
    comment_num = 20,
    content = '这是博客的文章内容。有很多很多很多很多的描述。。。。',
    create_time = '2020年12月10日 13:11:28',
    update_time = '2020年12月18日 18:11:28'
)

article = Article.objects.get(title='这是我的第三篇博客')
article
article.info

# 修改
article.info = '信息被修改了'

# 保存
article.save()

# 查询
article = Article.objects.get(title='这是我的第三篇博客')
article.title
article.info

05.让模型打印显示中文

新建模型:index/models.py

class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
     
    def __str__(self):
        return "Person({},{})".format(self.name, self.age)

迁移

python manage.py makemigrations
python manage.py migrate

进入shell

python manage.py shell

06.新增数据的方法

方法1:

Person.objects.create(name='root1',age=11)

方法2:

p = Person(name="root2", age=23)
p.save()

p = Person(name="root3")
p.age = 23
p.save()

方法3:

Person.objects.get_or_create(name="root4", age=23)
  • 这种方法是防止重复很好的方法,但是速度要相对慢些
  • 返回一个元组,第一个为Person对象,第二个为True或False
  • 新建时返回的是True, 已经存在时返回False

07.获取数据的方法

方法1:获取所有

Person.objects.all()

方法2:切片取前十个

# 切片操作,获取10个人,不支持负索引,切片可以节约内存
Person.objects.all()[:10]

方法3:根据指定属性

Person.objects.get(name='root1')
Person.objects.get(name='root4', age=23)
  • get是用来获取一个对象的
  • 如果需要获取满足条件的一些人,就要用到filter

方法4:过滤

# 等于Person.objects.filter(name__exact="root") 名称严格等于 "root" 的人
Person.objects.filter(name="root")

方法5:过滤,不区分大小写

Person.objects.create(name='ABC', age=23)
Person.objects.create(name='aBC', age=23)
Person.objects.create(name='AbC', age=23)
Person.objects.create(name='ABc', age=23)
Person.objects.create(name='Abc', age=23)

# 名称为 abc 但是不区分大小写,可以找到 ABC, Abc, aBC,这些都符合条件
Person.objects.filter(name__iexact="abc")  

方法6:过滤,包含

# 名称中包含 "abc"的人
Person.objects.filter(name__contains="abc")

方法7:过滤,包含且不区分大小写

#名称中包含 "abc",且abc不区分大小写
Person.objects.filter(name__icontains="abc")

方法8:过滤,正则表达式

# 正则表达式查询
Person.objects.filter(name__regex="^abc")

方法9:过滤,正则表达式不区分大小写

# 正则表达式不区分大小写
Person.objects.filter(name__iregex="^abc")

方法10:过滤,排除

# 排除包含 root 的Person对象
Person.objects.exclude(name__contains='root')

方法11:过滤+排除

# 找出名称含有abc, 但是排除年龄是23岁的
Person.objects.filter(name__contains="abc").exclude(age=23)

08.排序方法

方法1:正序

Person.objects.all().order_by('age')

方法2:倒序

# 在age前加一个负号,可以实现倒序
Person.objects.all().order_by('-age') 

09.表关系

修改index/models.py

from django.db import models
 
 
class Author(models.Model):
    name = models.CharField(max_length=50)
    qq = models.CharField(max_length=10)
    addr = models.TextField()
    email = models.EmailField()
 
    def __str__(self):
        return self.name
 
 
class Article(models.Model):
    title = models.CharField(max_length=50)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    content = models.TextField()
    score = models.IntegerField()  # 文章的打分
    tags = models.ManyToManyField('Tag')
 
    def __str__(self):
        return self.title
 
 
class Tag(models.Model):
    name = models.CharField(max_length=50)
 
    def __str__(self):
        return self.name

复杂的表关系

  • 一对多关系:假设一篇文章只有一个作者(Author),一个作者可以有多篇文章(Article)
  • 多对多关系:一篇文章可以有多个标签(Tag)。

创建 migrations 然后 migrate 在数据库中生成相应的表

python manage.py makemigrations
python manage.py migrate

进入shell

python manage.py shell

导入依赖

from index.models import Article,Author,Tag

10.准备数据

zhangsan = Author.objects.create(name='张三', qq='111222', addr='北京', email='zhangsan@qq.com')
lisi = Author.objects.create(name='李四', qq='111222', addr='北京', email='zhangsan@qq.com')
wangwu = Author.objects.create(name='王五', qq='111222', addr='北京', email='zhangsan@qq.com')

tag1 = Tag.objects.create(name='python')
tag2 = Tag.objects.create(name='java')
tag3 = Tag.objects.create(name='微服务')

article1 = Article.objects.create(
    title='文章1', 
    author=zhangsan, 
    content='内容', 
    score=100
)

article1.tags.add(tag1)
article1.tags.add(tag2)
article1.tags.add(tag3)

article2 = Article.objects.create(
    title='文章2', 
    author=zhangsan, 
    content='内容', 
    score=100
)

article2.tags.add(tag1)
article2.tags.add(tag2)
article2.tags.add(tag3)

article3 = Article.objects.create(
    title='文章3', 
    author=lisi, 
    content='内容', 
    score=100
)

article3.tags.add(tag1)
article3.tags.add(tag2)
article3.tags.add(tag3)

article4 = Article.objects.create(
    title='文章4', 
    author=wangwu, 
    content='内容', 
    score=100
)

article4.tags.add(tag1)
article4.tags.add(tag2)
article4.tags.add(tag3)

11.查看执行的SQL语句

str(Author.objects.all().query)
str(Author.objects.filter(name="张大鹏").query)

12.获取元组形式结果

authors = Author.objects.values_list('name', 'qq')
authors

如果只需要 1 个字段,可以指定 flat=True

Author.objects.values_list('name', flat=True)

查询 张三 这个人的文章标题

Article.objects.filter(author__name='张三').values_list('title', flat=True)

13.获取字典形式结果

比如我们要获取作者的 name 和 qq

Author.objects.values('name', 'qq')

查询 张三 这个人的文章标题

Article.objects.filter(author__name='张三').values('title')

14.聚合查询

我们来计算一下每个作者的文章数(我们每个作者都导入的Article的篇数一样,所以下面的每个都一样)

from django.db.models import Count

# 根据author分组 统计文章数量
Article.objects.all().values('author_id').annotate(count=Count('author')).values('author_id', 'count')

我们也可以获取作者的名称 及 作者的文章数

Article.objects.all().values('author__name').annotate(count=Count('author')).values('author__name', 'count')

求一个作者的所有文章的得分(score)平均值

from django.db.models import Avg
Article.objects.values('author_id').annotate(avg_score=Avg('score')).values('author_id', 'avg_score')

求一个作者所有文章的总分

from django.db.models import Sum
Article.objects.values('author__name').annotate(sum_score=Sum('score')).values('author__name', 'sum_score')

15.打印SQL语句

开始之前我们修改一个 settings.py 让Django打印出在数据库中执行的语句

settings.py 尾部加上

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG' if DEBUG else 'INFO',
        },
    },
}

这样当 DEBUG 为 True 的时候,我们可以看出 django 执行了什么 SQL 语句


版权声明:本文为qq_37703224原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。