Django入门 ----ORM数据的增删改查


Django的对象关系映射系统(Object-Relational Mapper, ORM)提供了丰富的数据查询接口, 无需使用原生SQL语句即可通过对模型的简单操作实现对数据库里的数据进行 增删改查。查询得到的结果叫 查询集(QuerySet), 所以这个接口被称为QuerySet API

Article模型如下所示:

from django.db import models

class Article(models.Model):
    title = models.CharField('标题', max_length=200, unique=True)
    body = models.TextField('正文')
    created = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.title

1. 增

1. 方法1:save()

from .models import Article

article = Article(title="My first article", body="My first article body")
article.save()
  • 该方法如果不主动save(), 创建的对象实例只会存于内存之中,不会保存到数据库中,create方法弥补了该缺点

2. 方法2:create()

article = Article.objects.create(title="My first article", body="My first article body")
  • 为了避免重复创建数据表中已存在的条目,Django还提供了get_or_create()。它会返回查询到的或新建的模型对象实例,还会返回这个对象实例是否是刚刚创建的
obj, created = Article.objects.get_or_create(title="My first article", body="My first article body")
  • 对Django自带auth模块中的User模型操作,比如创建新的用户时,使用用create_user()。该方法会将密码自动加Hash存储到数据库中
from django.contrib.auth.models import User
user = User.objects.create_user(username='john, email='john@gmail.com',password='somepwd')

3. 方法3:bulk_create()

  • 向数据库中插入多条数据时,每使用save或create方法保存一条就会执行一次SQL。而**bulk_create()**可以一次SQL添加多条数据,效率要高很多
# 内存生成多个对象实例
articles  = [Article(title="title1", body="body1"), Article(title="title2", body="body2"), Article(title="title3", body="body3")]

# 执行一次SQL插入数据
Article.objects.bulk_create(articles)

2. 删

# 1. 删除一条数据
Article.objects.get(pk=5).delete() 

# 2. 删除多条数据
Article.objects.filter(title__icontains="python").delete() 

# 3. 删除全部数据
Article.objects.all().delete() 

3. 改

1. 方法1:save()

article = Article.objects.get(id=1)
article.title = "New article title"
article.save()

2. 方法2:update()

# 1. 更新单条数据
article = Article.objects.get(id=1).update(title='new title')

# 2. 更新多条数据
article = Article.objects.filter(title__icontains='python').update(title='Django')

3. 方法3:bulk_update()

# 一次性更新多条数据
articles = [Article.objects.get(id=1), Article.objects.get(id=2)]

articles [0].title = "new title 1"
articles [1].title = "new title 2"

Article.objects.bulk_update(articles, ["title"])

4. 查

1. 查询所有数据

# QuerySet类型,实例对象列表,方法:all()
Article.objects.all() 
# 字典列表
Article.objects.all().values() 
# 只获取title-字典形式
Article.objects.all().values('title') 
# 只获取title列表- 元组形式,只有value,没有key
Article.objects.all().values_list('title')
# 只获取title列表,只有value
Article.objects.all().values_list('title', flat=True)

2. 查询一条数据

# id 不存在会报错,方法:get()
article = Article.objects.get(id=11)
# id 不存在不会报错,方法:filter()
article = Article.objects.filter(id=1).first()
# 更好的方法,方法:get_object_or_404()
from django.shortcuts import get_object_or_404 
article = get_object_or_404(Article, pk=1) 

3. 查询多条数据

1. 按大于、小于及不等于查询
# gte:大于等于,lte:小于等于
articles = Article.objects.filter(id__gte=2).filter(id__lte=11)
# 不等于
articles = Article.objects.exclude(id=10)
2. 按范围查询
# 按范围查询,in或者range
articles = Article.objects.filter(id__range=[2, 11])
articles = Article.objects.filter(id__in=[3, 6,9])
3. 字符串模糊查询
#标题包含python,若忽略大小写使用 icontains
articles = Article.objects.filter(title__contains='python')

#标题以python开头,若忽略大小写使用 istartswith
articles = Article.objects.filter(title__startswith='python')

#标题是python结尾的,若忽略大小写使用 iendswith
articles = Article.objects.filter(title__endswith='python')
4. 按日期时间查询
# 查询2021年发表的文章
Article.objects.filter(created__year=2021)

# 查询2021年3月19日发表的文章
import datetime
Article.objects.filter(created__date=datetime.date(2021,3,19))

# 查询2021年1月1日以后发表的文章
Article.objects.filter(created__gt=datetime.date(2021, 1, 1))

# 与当前时间相比,查询即将发表的文章
from django.utils import timezone
Article.objects.filter(created__gt=timezone.now())

# 按绝对时间范围查询,查询2021年1月1日到6月30日发表文章
article = Aritlce.objects.filter(created__gte=datetime.date(2021, 1, 1),
pub_date__lte=datetime.date(2021, 6, 30))

# 按相对时间范围查询,用range查询3月1日以后30天内发表文章
startdate = datetime.date(2021, 3, 1)
enddate = startdate + datetime.timedelta(days=30)
Article.objects.filter(pub_date__range=[startdate, enddate])

4. 切片、排序、去重

# 切片
articles = Article.objects.filter(created__year=2021)[:5]

# 排序:created正序,-表示逆序
articles = Article.objects.all().order_by('-created')

# 去重
Article.objects.filter(title__icontains='python').distinct()

5. 高级Q和F方法

  • Q方法
    执行or逻辑的条件查询,可以使用Q方法,它可以连接多个查询条件,Q对象前面加 ~ 可以表示否定
from django.models import Q
# 查询标题含有python或Django的文章
article = Article.objects.filter(Q(title__icontains='python')|Q(title__icontains='django'))
# 查询标题含有python,不含有Django的文章
article = Article.objects.filter(Q(title__icontains='python')|~Q(title__icontains='django'))
  • F方法
    基于自身字段值来过滤一组对象,还支持加、减、乘、除、取模和幂运算等算术操作
from django.db.models import F
Article.objects.filter(n_commnets__gt=F('n_pingbacks'))
Article.objects.filter(n_comments__gt=F('n_pingbacks') * 2)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值