单表查询

一.数据库相关设置

''' 
# Mysql连接配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db_name',
        'HOST': '127.0.0.1',
        'USER': 'root',
        'PASSWORD': 'root'
    }
}

# 配置ORM的loggers日志
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }
}
'''

'''
class User(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=16)
    age = models.IntegerField()
    birthday = models.DateField()
'''

二、测试文件运行Django项目

'''
1. 加载项目配置文件
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "项目名.settings")
2. 启动Django
import django
django.setup()
3. 使用项目中的各个模块
from my_app.models import User
'''

三、简单增删改查

Django的Queryset和objects对象

'''
1. QuerySet是查询集,就是传到服务器上的url里面的内容。Django会对查询返回的结果集QerySet进行缓存,这里是为了提高查询效率。也就是说,在你创建一个QuerySet对象的时候,Django并不会立即向数据库发出查询命令,只有在你需要用到这个QuerySet的时候才回去数据库查询。

2. Objects是django实现的mvc框架中的数据层,django中的模型类都有一个objects对象,它是一个django中定义的QuerySet类型的对象,它包含了模型对象的实例。

简单的说,Objects是单个对象,QuerySet是许多对象。

QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作。只要你查询的时候才真正的操作数据库。
'''

1、增

'''
User.objects.create(name='henry',age='30',birthday='1989-10-13')

user = User(name='wendy',age='25',birthday='1994-8-28')
user.save()
'''

2、查

'''
# 操作的结果是一个list,类型是queryset
u_list = User.objects.filter(name='henry')

# 只能操作有且只有一条数据的记录
user = User.objects.get(id=1)

try:
    u2 = User.objects.get(name='wendy')
    print(u2)
except Exception:
    print('wendy对象不唯一!')
'''

3、改

'''
User.objects.filter(id=2).update(birthday='1994-10-3')

user=User.objects.filter(name='wendy')[0]
user.birthday = '1994-8-28'
user.save()
'''

4、删

'''
User.objects.filter(id=1).delete()

user = User.objects.filter(name='wendy')[0]
user.delete()
'''

四、单表操作函数

'''
1. all():查询所有结果list,类型是QuerySet,支持正向索引取值[i],支持索引切片[m:n]
QuerySet对象具有query属性,里面存放的的是得到该结果执行的sql语句(ORM内部还存在对sql语句的优化)
支持正向索引(不支持反向索引,原因是数据过多时,不能将数据一次性查出,需要分批次按需求查出)
u_l=User.objects.all()[1:3] 得到索引为1,2的两条数据

2. filter(**kwargs):查询结果是一个包含满足条件的所有数据的列表,类型为QuerySet			  

3. get(**kwargs):查询满足条件的唯一对象obj,查询结果不为obj则抛出异常		  

4. exclude(**kwargs):查询结果是一个包含满足条件的对立面的所有数据的列表,类型为QuerySet

5. order_by(*field):查询按照指定字段进行排序后的所有结果,返回值是一个list,类型为QuerySet,'tag_name'代表正序,'-tag_name'代表降序
User.objects.order_by('id')  #按照id正序排序
User.objects.order_by('-id')  #按照id降序排序

6. reverse():反转排序查询的所有结果,返回值为一个list
User.objects.order_by('id').reverse()

7. count():统计返回查询结果list的长度
count = User.objects.all().count()

8. first():返回查询结果中的第一个对象obj

9. last():返回查询结果中的最后一个对象obj

10. exists():判断查询结果是否存在,值为布尔类型
res = User.objects.filter(id=6).exists()
print(res)

11. values(*field):按照指定字段(们)进行查询,返回存放包含字段(们)的字典类型的列表list
u_l5_dic = User.objects.values('id','name')
print(u_l5_dic)
结果:<QuerySet [{'id': 1, 'name': 'henry'}, {'id': 2, 'name': 'wendy'}>

12. values_list(*field):与values(*field)类似,但返回值是存放数据的元组类型的列表list
u_l6 = User.objects.values_list('id','name')
print(u_l6)
结果:<QuerySet [(1, 'henry'), (2, 'wendy')]>

13. distinct():从查询结果中剔除重复字段(一般和values结合使用),不能对数据库进行去重操作,只是在结果中剔除了重复的字段
u_17 = User.objects.values('name','age','birthday').distinct()
print(u_17)
'''
'''
配置ORM的loggers日志
print(user_list)  #得到的sql语句是经过ORM框架优化后的sql语句,是真正交给pymysql执行的sql语句
print(user_list.query)  #结果是将这个对象转化为sql语句的初步sql
'''

五、模糊查询

'''
user_list = User.objects.filter(id__gte=1)

# 整型相关
age__exact=8  # 确切匹配8
age__in=[8, 10]  # 8或10
age__gt=8  # 大于8
age__gte=8  # 大于等于8
age__lt=8  # 小于8
age__lte=8  # 小于等于8
age__range=[8, 10]  # 8到10之间

age__isnull=0|1  
u_111 = User.objects.filter(id__isnull=1)  # 1:该字段为空的所有数据 | 0:该字段不为空的所有数据

# 字符串相关
name__startswith  # 后方模糊匹配
u_l12 = User.objects.filter(name__startswith='s')
print(u_l12)

name__endswith  # 前方模糊匹配
u_l13 = User.objects.filter(name__endswith='y')
print(u_l13)

name__contains  # 前后方均模糊匹配
u_l14 = User.objects.filter(name__contains='n')
print(u_l14)

name__regex  # 正则匹配
u_l15 = User.objects.filter(name__regex="n{1,}") #名字中含有一个或多个n
print(u_l15)
在这里正则匹配不能用\w代表所有字母数字,这样会被解析成是否含有\w这个字符,而是要用[a-zA-Z0-9]代替
u_l16 = User.objects.filter(name__iregex="[a-zA-Z0-9]{1,}") #名字中含有一个或多个字符
print(u_l16)

name__istartswith  # 不区分大小写后方模糊匹配(i开头就是不区分大小写)
u_l17 = User.objects.filter(name__istartswith='s')
print(u_l17)

# 时间相关
birthday__year=2008  # 时间年份模糊匹配
u_l18 = User.objects.filter(birthday__year=1989)
print(u_l18)
'''

六、F与Q查询

'''
from django.db.models import F, Q
# F基于计算 F('字段名')
# 案例一:将id为1的结果年龄增加1
User.objects.filter(id=1).update(age=F('age')+1) #age=age+1 是错误的,update不能完成二步操作

# 案例二:查询id是年龄1/4的结果
user = User.objects.filter(id=F('age')/6)

#>> 与 <<
print(8>>1) => 4
print(8<<1) => 16



# Q基于关系 Q('字段条件')
u_l19 = User.objects.filter(name__regex='henry',age=30) #默认是与关系 &
print(u_l19)
# 与 &
User.objects.filter(Q(id=1) & Q(age=30))  # id=1 并且 age=30

# 或 |
User.objects.filter(Q(id=1) | Q(id=2))  # id=1 或 id=2
User.objects.filter(Q(age__lt=20) | Q(name__icontains='a')) #年龄小于20或姓名包含a

# 非 ~
User.objects.filter(~Q(id=1))  # id 不为 1
User.objects.filter(~Q(age__lte=25)) #年龄不小于等于25

'''