字段查询

对sql中where的实现,作为方法filter(),exclude(),get()的参数
语法:属性名称__比较运算符=值
外键:属性名_id
转义:   like语句中使用%是为了匹配占位,匹配数据中的 % ( where like '\%' )

  filter(sname__contains='%')

查询条件

  • 属性__运算符=值
  • in:是否包含在范围内,filter(pk__in=[2,4,6,8])
  • contains  类似于 模糊查询 like,大小写敏感,filter(sname__contains='赵')
  • startswith  以xx开始  本质也是like,以values开头或结尾,大小写敏感
  • endswith 以 xx 结束  也是like
  • exact:判断,大小写敏感,filter(isDelete =
    False)
  • gt,gte,lt,lte:大于,大于等于,小于小于等于filter(sage__gt=30)
  • isnull,isnotnull:是否为空,filter(sname__isnull=False)
  • 前面同时添加i , ignore 忽略大小写的匹配

    • iexact
    • icontains
    • istartswith
    • iendswith

时间的

year,month,day,week_day,hour,minute,second:
  filter(lasttime__year=2017)

实践:时间运算符的坑

我们在models.py中添加订单模型

# 订单
class Order(models.Model):
    o_num = models.CharField(max_length=16, unique=True)
    o_time = models.DateTimeField(auto_now_add=True)  # 自动添加时间

然后迁移至数据库
然后我们可以添加数据其中
之前我们学过添加数据的方式有:
1.在views中编写函数添加
2.直接打开数据库添加
现在我们有了第三种方法:利用shell快速添加

(venv) E:\DJ>python manage.py shell
Python 3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 14 2019, 23:09:19) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from two.models import Order
>>> order = Order()
>>> order.o_num= '110'
>>> order.save()

查看数据库可得:(时间比北京时间差了8个小时)

我们新建一个路由url(`'getorders/',views.get_orders)`, 
接着添加views函数:

def get_orders(request):
    orders = Order.objects.filter(o_time__month=2)
    for order in orders:
        print(order.o_num)
    return HttpResponse('获取订单成功')

我们查询2月份的订单号(按年份查询没有问题)
这时发现:

订单获取成功,但是没有打印出订单号
这是因为:

  • django中查询条件有时区问题
  • 解决办法:

    • 关闭django中自定义的时区

在settings.py中将USE_TZ 改为False

  • 在数据库中创建对应的时区表(麻烦)

修改完成之后再次尝试:
成功

查询快捷:

pk:代表主键,filter(pk=1)

跨关系查询:

模型类名__属性名__比较运算符,实际上就是处理的数据库中的join
grade
= Grade.objects.filter(student__scontend__contains='楚人美')
描述中带有'楚人美'这三个字的数据属于哪个班级

比如说:有班级和学生,有一些班级,每个班级有一些学生,需求是查询班级哪个班级有小明的同学,查出来班级

实践:跨关系查询

我们新建立俩个模型,班级和学生

class Grade(models.Model):
    g_name = models.CharField(max_length=16)


class Student(models.Model):
    s_name = models.CharField(max_length=16)
    s_grade = models.ForeignKey(Grade,on_delete=models.CASCADE)

接着插入数据


我们查询包含赵六的班级
我们先添加url:url(`'getgrades/', views.get_grades)`,
接着在views函数中添加:

def get_grades(request):
    grades = Grade.objects.filter(student__s_name='赵六')
    for grade in grades:
        print(grade.g_name)
    return HttpResponse('获取成功')

第二行我们调查grades,利用极联查出赵六所在的班级名称

结果如下:

聚合函数

使用aggregate()函数返回聚合函数的值
Avg:平均值
Count:数量
Max:最大
Min:最小
Sum:求和
Student.objects().aggregate(Max('sage'))

实践:聚合函数

models中创建消费者模型

class Customer(models.Model):
    c_name = models.CharField(max_length=16)
    c_cost = models.IntegerField(default=10)

shell中添加数据

添加url:url('getcustomer',views.get_customer),
添加views函数:

def get_customer(request):
    result = Customer.objects.aggregate(Max('c_cost'))# 使用聚合函数,Max需要导入包
    print(result)
    return HttpResponse('获取花费成功')

F对象


可以使用模型的A属性与B属性进行比较
`grades
= Grade.objects.filter(ggirlnum__gt=F('gboynum') )<br />F对象支持算数运算<br />grades
= Grade.objects.filter(ggirlnum__gt=F('gboynum') +10 )`

实践:获取公司中女生人数比男生人数多的公司名字

明确查询的是公司,结果也是公司,只不过条件不是公司,而是人数
建模:

class Company(models.Model):
    c_name = models.CharField(max_length=16)
    c_girl_num = models.IntegerField(default=5)
    c_boy_num = models.IntegerField(default=3)

迁移
添加数据:


url:url('getcompany',views.get_company),
views:

def get_company(request):
    companies = Company.objects.filter(c_boy_num__lt=F('c_girl_num'))

    for company in companies:
        print(company.c_name)
    return HttpResponse('获取公司成功')

结果:

Q

  • 可以对条件进行封装
  • 封装之后,可以支持逻辑运算

    • 与  &  and
    • 或  |   or
    • 非   ~  not

实践:同时筛选出男生大于1,女生大于5的人数

def get_company(request):
    # 封装之后支持逻辑运算
    companies = Company.objects.filter(Q(c_boy_num__gt=1) & Q(c_girl_num__gt=5))
    for company in companies:
        print(company.c_name)
    return HttpResponse('获取公司成功')

原来可以用连续的filter来筛选

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏