Django(数据查询)

如何治单独测试django中的某一个py文件

书写测试脚本:

  - 在应用下的tests.py或者自己建一个py文件

  - 在文件中书写以下内容:

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()

创建表格:

class Movie(models.Model):
    title = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_time = models.DateField()  # 年月日

create():创建数据,返回值就是当前被创建数据的对象本身

models.Movie.objects.create(title=‘齐天大圣‘,price=999.23,publish_time=‘2016-1-1‘)

all():查询所有数据,返回的是queryset对象

res = models.Movie.objects.all()

fileter():按照一定条件查询,条件可以是多个,条件直接关系是and,返回的是queryset对象

res = models.Movie.objects.filter(pk=1,title=‘python入门‘)

get():直接获取对象本身,但是不推荐使用,因为当查询条件不存在时候,会报错

res = models.Movie.objects.get(pk=1)

values():获取指定字段的值,返回的是一个列表套字典的queryset对象

res = models.Movie.objects.values(‘title‘,‘publish_time‘)

values_list():获取指定字段的值,返回的是一个列表套元组的queryset对象

res = models.Movie.objects.values_list(‘title‘,‘price‘)

first():取第一个元素对象

res = models.Movie.objects.filter().first()

last():取最后一个元素对象

res = models.Movie.objects.last()

update():更新数据,返回的是受影响的行数

res = models.Movie.objects.filter(pk=1).update(title=‘齐天大圣2‘,price=666)

delete():删除数据,返回的是受影响的表和行数

res = models.Movie.objects.filter(pk=3).delete()

count():统计数据条数

res = models.Movie.objects.count()

order_by():按照指定字段排序,默认是升序,前面加减号就是降序

res = models.Movie.objects.order_by(‘price‘)  # 升序

res = models.Movie.objects.order_by(‘-price‘)  # 降序

exclude():排除什么之外,少选条件

res = models.Movie.objects.exclude(pk=1)

exists():判断前面的对象是否有数据,返回的是布尔值

res = models.Movie.objects.filter(pk=1000).exists()

reverse():反转

res = models.Movie.objects.order_by(‘price‘).reverse()

distinct():去重

res = models.Movie.objects.values(‘title‘,‘price‘).distinct()

双下划线查询

__gt:大于

res = models.Movie.objects.filter(price__gt=200)

__lt:小于

res = models.Movie.objects.filter(price__lt=500)

__gte:大于等于

res = models.Movie.objects.filter(price__gte=200)

__lte:小于等于

res = models.Movie.objects.filter(price__lte=500)

__in:在XX中

res = models.Movie.objects.filter(price__in=[123,666,876])

__range:在一个区间内,顾头也顾尾

res = models.Movie.objects.filter(price__range=(200,900))

__contains:模糊查询,默认是区分大小写,前面加i不区分

res = models.Movie.objects.filter(title__contains=‘p‘)  # 区分‘p’的大小写

res = models.Movie.objects.filter(title__icontains=‘p‘)  # 不区分‘p’的大小写

__year/month/day...:查询指定的年或者月或天等其他的时间

res = models.Movie.objects.filter(publish_time__year=2014)

res = models.Movie.objects.filter(publish_time__month=1)

外键字段的增删改查

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)  # 该字段新增数据自动添加 无需考虑

    # 出版社   一对多    外键字段建在多的一方
    publish = models.ForeignKey(to=‘Publish‘)
    # 作者     多对多    外键字段建在任意一方均可 推荐你建在查询频率较高的表
    authors = models.ManyToManyField(to=‘Author‘)

    # 库存数
    kucun = models.BigIntegerField(default=1000)
    # 卖出数
    maichu = models.BigIntegerField(default=1000)

book表

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)

publish表

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    # 作者详情   一对一    外键字段建在任意一方均可 推荐你建在查询频率较高的表
    author_detail = models.OneToOneField(to=‘AuthorDetail‘)

author表

class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=32)

authorDetail表

一对多

:两种方式

  - 直接写实际的表字段

  models.Book.objects.create(title=‘大闹天宫‘,price=123.23,publish_id=2)

  - 添加对象

  publish_obj = models.Publish.objects.get(pk=1)

  models.Book.objects.create(title=‘哪吒闹海‘,price=66.66,publish=publish_obj)

:两种方式 

  - 直接写实际的表字段

  models.Book.objects.filter(pk=1).update(publish_id=3)

  - 添加对象

  publish_obj = models.Publish.objects.get(pk=4)

  models.Book.objects.filter(pk=1).update(publish=publish_obj)

多对多

给书籍绑定作者关系:add

add专门给第三张关系表添加数据,括号内即可以传数字也可以传对象,并且都支持传多个

book_obj = models.Book.objects.filter(pk=1).first()
# 书籍和作者的关系是由第三张表绝对 也就意味着你需要操作第三张表
book_obj.authors.add(1)  # 给书籍绑定一个主键为1的作者
book_obj.authors.add(2,3)    # 也可以一次绑定多个作者

移除书籍与作者的绑定关系:remove

remove专门给第三张关系表移除数据,括号内即可以传数字也可以传对象,并且都支持传多个

book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.remove(2)
book_obj.authors.remove(1,3)

修改书籍与作者的关系 :set

set修改书籍与作者的关系 ,括号内支持传数字和对象,但是需要是可迭代对象

book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.set((3,))
book_obj.authors.set((2,3))

author_obj = models.Author.objects.get(pk=2)
author_obj1 = models.Author.objects.get(pk=3)
book_obj.authors.set([author_obj,author_obj1])

清空书籍与作者关系:clear

clear清空关系,不需要任何的参数

book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.clear()

跨表查询

正反向:

  正向:跨表查询的时候,外键字段是否在当前数据对象中,如果在,查询另外一张关系表方式叫正向查询

  反向: 如果不在,就是反向查询

口诀:

  正向查询按外键字段

  反向查询按表名小写

基于对象的跨表查询(子查询)

1.查询书籍pk为1的出版社名称

book_obj = models.Book.objects.filter(pk=1).first()
res = book_obj.publish.name

2.查询书籍pk为2的所有作者的姓名

book_obj = models.Book.objects.filter(pk=2).first()
# print(book_obj.authors)  # 返回的是:app01.Author.None
author_list = book_obj.authors.all()
for author_obj in author_list:
    print(author_obj.name)

3.查询作者pk为1的电话号码

author_obj = models.Author.objects.filter(pk=1).first()
res = author_obj.author_detail.phone

小结:正向查询的时候,当外键字段对应的数据可以有多个的时候需要加.all(),若没有多个,则点外键字典即可获取到对应的数据对象

4.查询出版社名称为东方出版社出版过的书籍

publish_obj = models.Publish.objects.filter(name=‘东方出版社‘).first()
# print(publish_obj.book_set)  # app01.Book.None
res = publish_obj.book_set.all()

5.查询作者为jason写过的书

author_obj = models.Author.objects.filter(name=‘jason‘).first()
res = author_obj.book_set.all()

6.查询手机号为120的作者姓名

author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
res = author_detail_obj.author.name

小结:基于对象的反向查询,表名小写是否需要加_set.all()

基于双下划线跨表查询(链表查询)

1.查询书籍pk为1的出版社名称

正向:

res = models.Book.objects.filter(pk=1).values(‘publish__name‘)  # 写外键字段,就意味着你已经在外键字段管理的那张表中

反向:

# res = models.Publish.objects.filter(book__pk=1)  # 出版社pk为1的书籍对应的出版社
res = models.Publish.objects.filter(book__pk=1).values(‘name‘)

2.查询书籍pk为1的作者姓名和年龄

正向:

res = models.Book.objects.filter(pk=1).values(‘title‘,‘authors__name‘,‘authors__age‘)

反向:

res = models.Author.objects.filter(book__pk=1).values(‘name‘,‘age‘)

3.查询作者是jason的年龄和手机号

正向:

res = models.Author.objects.filter(name=‘jason‘).values(‘age‘,‘author_detail__phone‘)

反向:

res = models.AuthorDetail.objects.filter(author__name=‘jason‘).values(‘phone‘,‘author__age‘)

4.查询书籍pk为的1的作者的手机号

正向:

res = models.Book.objects.filter(pk=1).values(‘authors__author_detail__phone‘)

反向:

res = models.AuthorDetail.objects.filter(author__book__pk=1).values(‘phone‘)

小结:只要表之间有关系,你就可以通过正向的外键字段或者反向的表名小写连续跨表操作

聚合查询

from django.db.models import Max,Min,Avg,Count,Sum
# 查询所有书的平均价格
res = models.Book.objects.aggregate(avg_num=Avg(‘price‘))
print(res)
# 查询价格最贵的书
res = models.Book.objects.aggregate(max_num=Max(‘price‘))
print(res)
# 全部使用一遍
res = models.Book.objects.aggregate(Avg("price"), Max("price"), Min("price"),Count("pk"),Sum(‘price‘))
print(res)

分组查询

# 1.统计每一本书的作者个数
res = models.Book.objects.annotate(author_num=Count(‘authors‘)).values(‘title‘,‘author_num‘)
print(res)

# 2.统计出每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min(‘book__price‘)).values(‘name‘,‘min_price‘,‘book__title‘)
print(res)

# 3.统计不止一个作者的图书
res = models.Book.objects.annotate(author_num=Count(‘authors‘)).filter(author_num__gt=1).values(‘title‘)
print(res)

# 4.查询各个作者出的书的总价格
res = models.Author.objects.annotate(price_sum=Sum(‘book__price‘)).values(‘name‘,‘price_sum‘)
print(res)

F与Q查询

from django.db.models import F,Q

1.查询库存数大于卖出数的书籍

res = models.Book.objects.filter(kucun__gt=F(‘maichu‘))

2.将所有书的价格提高100

res = models.Book.objects.update(price=F(‘price‘) + 100)

3.查询书的名字是python入门或者价格是1000的书籍

res = models.Book.objects.filter(Q(title=‘python入门‘),Q(price=1000))  # 逗号是and关系
res = models.Book.objects.filter(Q(title=‘python入门‘)|Q(price=1000))  # |是or关系
res = models.Book.objects.filter(~Q(title=‘python入门‘)|Q(price=1000))  # ~是not关系

小结:F能获取到表中某个字段对应的值;Q能够改变查询的条件关系  and or not

Q的高阶用法

q = Q()
q.connector = ‘or‘  # q对象默认也是and关系  可以通过connector改变or
q.children.append((‘title‘,‘python入门‘))
q.children.append((‘price‘,1000))

res = models.Book.objects.filter(q)
print(res)

原文地址:https://www.cnblogs.com/hexianshen/p/12168405.html

时间: 2025-01-13 00:41:00

Django(数据查询)的相关文章

Django数据查询方法总结

__exact 精确等于 like 'aaa'__iexact 精确等于 忽略大小写 ilike 'aaa'__contains 包含 like '%aaa%'__icontains 包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains.__gt 大于__gte 大于等于__lt 小于__lte 小于等于__in 存在于一个list范围内__startswith 以-开头__istartswith 以-开头 忽略大小写__en

Django数据查询中对字段进行排序

第一种方法:使用order_by进行排序 Articlelist = Article.objects.filter(**kwargs).order_by('nid') Articlelist = Article.objects.filter(**kwargs).order_by('-nid') #倒序 Articlelist = Article.objects.order_by('-nid') 可以使用两个字段进行排序:用在第一个字段相等,用第二个来排序的情形 Articlelist = Art

django数据查询之聚合查询和分组查询

1.# 获取各区域的总数 # 获取各区域的总数 allnum = OperationTask.objects.filter(task_create_time__range=[starttime, stoptime]).values( 'task_area').annotate(c=Count('id')).values('task_area', 'c').order_by('-c')[:10] 原文地址:https://www.cnblogs.com/CGCong/p/11044256.html

Django 分页查询并返回jsons数据,中文乱码解决方法

一.引子 Django 分页查询并返回 json ,需要将返回的 queryset 序列化, demo 如下: # coding=UTF-8 import os from django.core import serializers from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.shortcuts import render from django.http import

django在验证登录页面时遇到的数据查询问题

数据库查询时针对不存在的用户名进行验证 django在查询数据库时,可以使用get和filter两种方法. 两者的区别 当数据库内不存在该数据时,get会返回异常,而filter会返回空. 当数据库内查询结果大于1条时,get会返回异常,而filter会返回一个包含多个对象的结果集. 原文地址:https://www.cnblogs.com/chenych/p/11018897.html

django前后端分离 form_03(验证,数据查询,代码优化)

1.优化代码 把form验证的返回报错写成一个共用的类 该类在工程下建立了一个uitls-tools.py class FormatErrMsg: @property #装饰器-属性方法 调用的时候不需要加() def error_msg(self): #self.get_json_data() 是form自带的友好的报错提示 返回的是一个字典 message = '' for error_params, v in self.errors.get_json_data().items(): err

django orm查询方法详解

目录 1.1.1 生成查询 1.1.2 创建对象 1.1.3 保存修改的对象 1.1.4 保存 ForeignKey 和 ManyToManyField 字段 1.1.5 检索对象 1.1.6 检索所有的对象 1.1.7 过滤检索特定对象 1.1.8 链接过滤 1.1.9 过滤结果集是唯一 1.2.1 结果集是延迟的 1.2.2 其他的QuerySet方法 1.2.3 限制 QuerySets 1.2.4 字段查找 1.2.5 跨关系查询 1.2.6 过滤器可参考模型字段 1.2.7 缓存查询集

django 数据库查询

class Poll(models.Model): slug = models.SlugField(unique_for_month='pub_date')question = models.CharField(maxlength=255)pub_date = models.DateTimeField()expire_date = models.DateTimeField() def __repr__(self):return self.question class Meta:get_lates

MongoDB数据查询

启动MongoDB:sudo service mongodb start,mongo 经测试,键可加引号也可不加,但是值一般要加引号,数值类型除外 MongoDB区分大小写,命名通常采用驼峰式命名法 MongoDB在使用数据库,插入集合等情况下,若数据库/集合不存在将自动创建 数据查询find() db.<集合名>.find({<键名>:<值>,...}) 格式化结果集:后加.pretty()即db.<CollectionName>.find({key:'v

用python操作mysql数据库(之数据查询结果返回字典类型)

#!/usr/bin/env python # -*- coding: utf-8 -*- import MySQLdb #建立连接 conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='1qaz#EDC',db='test_db') cur = conn.cursor(MySQLdb.cursors.DictCursor) #建立游标时,加上"MySQLdb.cursors.DictCursor",让数据查询结果返回字