模型
from django.db import models |
数据
sqlite> SELECT * FROM app01_userinfo; |
查询
基本查询
In [10]: UserInfo.objects.all()
Out[10]: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>values
In [12]: UserInfo.objects.all().values("username")
Out[12]: <QuerySet [{'username': '张珊'}, {'username': '李四'}]>values_list
In [14]: UserInfo.objects.all().values_list("username", "pwd")
Out[14]: <QuerySet [('张珊', '12344'), ('李四', '123456')]>
一对多
模型定义class UserType(models.Model):
# 用户类型 CEO 经理 主管 组长 员工 ...
caption = models.CharField(max_length=16)
class UserInfo(models.Model):
# 用户信息
username = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
user_type = models.ForeignKey('UserType')
# user_type_id(生成表中字段名)
- 创建
第1种方法In [3]: UserInfo.objects.create(username='老王',pwd='123',user_type=UserType.objects.get(id=2))
Out[3]: <UserInfo: UserInfo object>
多一次数据库查询
第2种方法In [4]: UserInfo.objects.create(username='王五',pwd='123',user_type_id=2)
Out[4]: <UserInfo: UserInfo object>
第三种方法data = {'pwd': '123', 'user_type_id': 2, 'username': '张无忌'}
In [13]: u = UserInfo(**data)
In [14]: u.save()
第四种方法In [15]: u = UserInfo()
In [16]: u.username = "周芷若"
In [17]: u.pwd = "123"
In [18]: u.user_type = 1 # 报错
In [19]: u.user_type_id = 1
In [20]: u.save()
- 查询
方法1In [30]: u_type_id = UserType.objects.get(caption="CE0").id
In [31]: UserInfo.objects.filter(user_type_id=u_type_id)
Out[31]: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
先查找出 外键id 主表过滤外键id集合
方法2In [32]: UserInfo.objects.filter(user_type__caption='CE0')
Out[32]: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
# 通过models模型定义的字段名(不是生成数据库的字段) user_type__caption 字段名__外键关联表的字段(两个下划线)
# 能操作方法和单表一致
In [38]: UserInfo.objects.filter(user_type__id__gte=1)
Out[38]: <QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
In [39]: UserInfo.objects.filter(user_type__caption='CE0').values("username", 'pwd')
Out[39]: <QuerySet [{'pwd': '12344', 'username': '张珊'}, {'pwd': '123456', 'username': '李四'}, {'pwd': '123', 'username': '周芷若'}]>
方法3只要是有关键关联 可以使用多次两下划线 __
2、三张表跨表操作
class Somthing(models.Model):
name = models.CharField(max_length=32)
class UserType(models.Model):
catption = models.CharField(max_length=32)
s = models.ForignKey('Somthing')
# ceo,经理 , 组长,...
class UserInfo(models.Model):
user = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
user_type = models.ForignKey('UserType')
UserInfo.objects.filter(user_type__s__name='xx')
多对多
class Book(models.Model): |
数据sqlite> SELECT * FROM app01_book;
1|莎士比亚
2|悲惨世界
3|性能之巅
4|高性能MySQL
sqlite> SELECT * FROM app01_tag;
1|IT
2|西方文学
3|文科
4|理科
5|技术
sqlite> SELECT * FROM app01_tag_b;
sqlite>
增
addIn [11]: tag = Tag.objects.get(id=2)
In [12]: tag.tag_name
Out[12]: '西方文学'
In [13]: Book.objects.get(id=1).name
Out[13]: '莎士比亚'
In [14]: Book.objects.get(id=2).name
Out[14]: '悲惨世界'
In [15]: tag.b.add(1) # 将 tag_id=2, book_id=1插入 第三张关联表中
In [16]: tag.b.add(2) # 将 tag_id=2, book_id=1插入 第三张关联表中
批量插入
In [17]: tag.b.add(1,2,3,4)
# 将 tag_id=2, book_id=1插入 第三张关联表中
# 将 tag_id=2, book_id=2插入 第三张关联表中
# 将 tag_id=2, book_id=3插入 第三张关联表中
# 将 tag_id=2, book_id=4插入 第三张关联表中
In [18]: tag.b.add(*[1,2,3,4]) # 效果同上相当于参数解包删
tag = Tag.objects.get(id=2)
In [19]: tag.b.remove(1) # 将 tag_id=2, book_id=1 删除此记录
In [20]: tag.b.remove(2,4) # 将 tag_id=2, book_id=2 tag_id=2, book_id=4 删除此记录
In [21]: tag.b.remove(*[1,2,3,4]) # 原理同上
clear
In [22]: tag.b.clear() # 相当于 DELECT FROM app01_tag_b WHERE tag_id=2;改
In [1]: from app01.models import *
In [2]: tag = Tag.objects.get(id=2)
In [4]: tag.b.set([2,3]) # 1、隐含操作 DELECT FROM appo1_tag_b WHER tag_id = 2
# 2、 将 tag_id=2, book_id=2 tag_id=2, book_id=3 插入查
In [2]: tag = Tag.objects.get(id=2)
In [12]: tag.b.all()
Out[12]: <QuerySet [<Book: Book object>, <Book: Book object>]>
通过标签的外键查书名
In [34]: tag = Tag.objects.prefetch_related('b').filter(id=2).first()
In [37]: for i in tag.b.all(): # 因为使用prefetch_related 此循环没有再次执行sql查找
...: print (i.name)
...:
莎士比亚
悲惨世界
性能之巅
高性能mysql
使用 prefetch_related 可以优化减少查询的次数
mysql> SELECT `app01_tag`.`id`, `app01_tag`.`tag_name` FROM `app01_tag` WHERE `app01_tag`.`id` = 2 ORDER BY `app01_tag`.`id` ASC LIMIT 1;
+----+--------------+
| id | tag_name |
+----+--------------+
| 2 | 西方文学 |
+----+--------------+
1 row in set (0.00 sec)
mysql> SELECT `app01_tag_b`.`tag_id` AS `_prefetch_related_val_tag_id`, `app01_book`.`id`, `app01_book`.`name`
FROM `app01_book`
INNER JOIN `app01_tag_b` ON `app01_book`.`id` = `app01_tag_b`.`book_id`
WHERE `app01_tag_b`.`tag_id` IN (2) ;
+------------------------------+----+----------------+
| _prefetch_related_val_tag_id | id | name |
+------------------------------+----+----------------+
| 2 | 1 | 莎士比亚 |
| 2 | 2 | 悲惨世界 |
| 2 | 3 | 性能之巅 |
| 2 | 4 | 高性能mysql |
+------------------------------+----+----------------+
4 rows in set (0.00 sec)