配置数据库

1
2
3
4
5
6
7
8
9
10
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': ''
},
}

ORM操作

  • 使用Django Shell
1
python mange.py shell
  • 添加数据
1
2
3
4
<Model>.objects.create(key=value, key=value, ...)
# 或
m = <Model>(key=value, key=value, ...)
m.save()
  • 查询数据
1
2
3
4
5
6
7
8
# QuerySet可链式查询
# QuerySet.query获得SQL查询语句
<Model>.objects.
all() -> QuerySet(<Model>) # select * from table
# 若需要格式化输出,可以在相应的Model类中添加 def __str__(self)
values(col1, col2) -> QuerySet(dict) # select col1, col2 from table
values_list(col1, col2) -> QuerySet(tuple) # select col1, col2 from table
order_by('col1', '-col2') # all()按col1升序排序,col2降序排序
1
2
3
filter(attr1=value1, attr2=value2, ...) # select * from where attr1 = value1 and attr2 = value2
exclude(attr1=value1, attr2=value2, ...) # select * from where attr1 <> value1 and attr2 <> value2
get(attr1=value1, attr2=value2, ...) # 只取一条数据,否则报错(try except)
1
2
3
4
5
6
7
8
9
10
11
# 查询谓词 __谓词
__exact # 等值匹配,可以查询Null
__contains # 包含特定值 like '%words%'
__startswith # 以words开始
__endswith # 以words结束
__gt # 大于
__gte # 大于等于
__lt # 小于
__lte # 小于等于
__in # in ('A', 'B')
__range # 范围查询(A, B) -> between A and B
  • 修改数据
1
2
3
4
# 单个修改
m = <Model>.objects.get()
# 修改m
m.save()
1
2
3
# 批量修改为同一值
ms = <Model>.objects.filter()
ms.update(key=value) -> int # 返回修改成功的数量
  • 删除数据

    添加字段伪删除

1
2
m = <Model>.objects.get()
m.delete() -> tuple(int, dict)
1
2
ms = <Model>.objects.filter()
m.delete()
  • F对象

    考虑并发情况

    若先获取,赋值再更新,出错

    info.like = F(‘like’)+1

    info.save

    -> update info set like = like+1 where ?

    1
    2
    3
    # 列出价格高于自己的书
    from django.db.models import F
    Book.objects.filter(price__gt=F('price'))
  • Q对象

    处理逻辑且&、逻辑或|、逻辑非~等操作

    1
    2
    from django.db.models import F
    <Model>.objects.filter(Q()&Q()|~Q())
  • 聚合查询

    整表聚合

    1
    2
    3
    from djange.db.models import *
    # Sum, Avg, Count, Max, Min
    <Models>.ojects.aggregate(结果变量名=聚合类型(col)) -> dict

    分组聚合

    1
    2
    m = <Model>.objects.values(col1, col2, ...)
    m.annotate(结果变量名=聚合类型(col)) -> QuerySet
  • 原生数据库操作

    1
    <Model>.objects.raw(sql) -> RawQuerySet # 只支持基础操作
    1
    2
    # 防注入
    <Model>.objects.raw(sql, [value1, value2])
    1
    2
    3
    from django.db import connection
    with connection.cursor() as cur:
    cur.execte(sql, 拼接参数)

    关系映射

  • 一对一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A(models.Model):
attr = models.CharField('', max_length=10)
class B(models.Model):
attr = models.OneToOneField(A, ondelete=级联删除)
# models.CASCADE 一起删除
# models.PROTECT 不删除
# SET_NULL设置ForeignKey null,需要指定null=True
# SET_DEFAULT讲ForeignKey设置为其默认值
a = A.objects.create()
B.objects.create(attr=value, a=a)
b = B.objects.create(attr=value, a_id=a.id)
# 正向查询
b.a.attr
# 反向查询
a.b.attr
  • 一对多
1
2
3
4
5
6
7
8
9
class A(models.Model):
attr = models.CharField('', max_length=10)
class B(models.Model):
attr = models.Foreign(A, ondelete=级联删除)
# 正向查询
b.a.attr
# 反向查询
bs = a.b_set.all()
bs = a.b_set.filter()
  • 多对多
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 需要依赖第三张表,Django无需手动创建
# 两个类任意一个类中ManyToManyField()
class A(models.Model):
attr = models.CharField('', max_length=10)
class B(models.Model):
<属性名可以定义为类名小写+s或其他任意> = models.ManyToManyField(A, ondelete=级联删除)
# 创建属性
a1 = A.objects.create()
a2 = A.objects.create()
b = a1.b_set.create()
a2.b_set.add(b)
# 或
b = B.objects.create()
a3 = b.a.create()
b.a.add(a1)
# 正向查询
b.a.all()/.filter()
# 反向查询
a.b_set.all()/.filter()

分页

1
2
3
4
5
6
paginator = Paginator(object_list, per_page)
# attr
count # 需要分页数据的对象总数
num_pages # 分页后的页面总数
page_range # 从1开始的range对象,用于激励当前页码数
per_page # 每页数据的个数
1
2
3
4
5
6
7
8
9
10
11
12
# page对象
page = paginator.page(number) # 获取页信息
# attr
object_list # 当前页上所有数据对象的列表
number # 当前页的序号,从一开始
paginator # 当前page对象相关的Paginator对象
# method
has_next() -> bool
has_previous() -> bool
has_other_pages() -> bool # 上一页或下一页
next_page_number() -> int
previous_page_number() -> int