zoukankan      html  css  js  c++  java
  • django系列5.2--ORM数据库的单表操作

    单表操作

    在views.py中添加对数据库的操作语句

    #在逻辑代码中导入你要操作的表
    from app import models
    
    def add_book(request):
        '''
        添加表记录
        :param request: http请求信息
        :return:
        '''
        models.Book(title='人间失格',price=12,pub_date='2012-12-12',publish='文学出版社')
    

    1.添加表记录

    方式1:实例化对象就是一条表记录

    from app import models
    
    
    obj = models.Book(title='复活',price=12,pub_date='2012-12-12',publish='小出版社')
    obj.save()
    

    方式2:(我们一般使用方式二添加)

    models.Book.objects.create(title='复活',price=12,pub_date='2012-12-12',publish='小出版社')
    

    方式3: 批量插入数据,这样先创建对象比较快(使用bulk_create)

    book_list = []
    for i in range(10):
        bk_obj = models.Book(
            name='robertx%s'%i,
            addr='中国%s'%i
        )
        book_list.append(bk_obj)
    
    models.Book.objects.bulk_create(book_list) #批量插入,速度快
    

    2.查询表记录

    查询所有的记录:

    obj = models.Book.objects.all()
    

    使用values的结果:

    obj = models.Book.objects.all().values()
    # <QuerySet [{'id': 1, 'title': '雪国列车2', 'pub_date': datetime.date(2012, 12, 1),
    

    常用的查询API:

    <1> all():                  查询所有结果,结果是queryset类型
    
    <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象,结果也是queryset类型 Book.objects.filter(title='linux',price=100) #里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,or关系的我们后面再学,直接在这里写是搞不定or的
    
    <3> get(**kwargs):          返回与所给筛选条件相匹配的对象,不是queryset类型,是行记录对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。捕获异常try。  Book.objects.get(id=1)
    
    <4> exclude(**kwargs):      排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操作昂,用这个exclude,返回值是queryset类型 Book.objects.exclude(id=6),返回id不等于6的所有的对象,或者在queryset基础上调用,Book.objects.all().exclude(id=6)            
    
    <5>  order_by(*field):       queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型
    models.Book.objects.all().order_by('price','id') #直接写price,默认是按照price升序排列,按照字段降序排列,就写个负号就行了order_by('-price'),order_by('price','id')是多条件排序,按照price进行升序,price相同的数据,按照id进行升序
    
    <6> reverse():              queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型
    
    <7> count():                queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。
    
    <8> first():                queryset类型的数据来调用,返回第一条记录 Book.objects.all()[0] = Book.objects.all().first(),得到的都是model对象,不是queryset
    
    <9> last():                queryset类型的数据来调用,返回最后一条记录
    
    <10> exists():              queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False.   空的queryset类型数据也有布尔值True和False,但是一般不用它来判断数据库里面是不是有数据,如果有大量的数据,你用它来判断,那么就需要查询出所有的数据,效率太差了,用count或者exits例:all_books = models.Book.objects.all().exists() #翻译成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是通过limit 1,取一条来看看是不是有数据
    
    <11> values(*field):        用的比较多,queryset类型的数据来调用,返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列.model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。
    
    <12> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
    <13> distinct():            values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录
    

    双下划线的单表查询

    Book.objects.filter(price__in=[100,200,300]) #price值等于这三个里面的任意一个的对象
    Book.objects.filter(price__gt=100)  #大于,大于等于是price__gte=100,别写price>100,这种参数不支持
    Book.objects.filter(price__lt=100)  # 小于 同大于,不包含边界值
    Book.objects.filter(price__range=[100,200])  #sql的between and,大于等于100,小于等于200
    Book.objects.filter(title__contains="python")  #title值中包含python的
    Book.objects.filter(title__icontains="python") #不区分大小写
    Book.objects.filter(title__startswith="py") #以什么开头,istartswith  不区分大小写
    Book.objects.filter(pub_date__year=2012)  # 日期查询,年份为2012的数据
    

    关于value的用法

    all_books = models.Book.objects.all().values('id','title')
    print(all_books) 
    #<QuerySet [{'title': 'linux', 'id': 6}, {'title': '你好', 'id': 7}, {'title': 'linux', 'id': 8}, {'title': 'xxx', 'id': 9}, {'title': 'gogogo', 'id': 10}]>
    
        '''
            values做的事情:
            ret = [] #queryset类型
            for obj in Book.objects.all():
                temp = {  #元素是字典类型
                    'id':obj.id,
                    'title':obj.title
                }
                ret.append(temp)
    
        '''
    

    关于时间问题:日期查询

    all_books = models.Book.objects.filter(pub_date__year=2012)   # 找2012年的所有书籍
    all_books = models.Book.objects.filter(pub_date__year__gt=2012)  # 找大于2012年的所有书籍
    all_books = models.Book.objects.filter(pub_date__year=2019,pub_date__month=2)  # 找2019年月份的所有书籍,如果明明有结果,你却查不出结果,是因为mysql数据库的时区和咱们django的时区不同导致的,了解一下就行了,你需要做的就是将django中的settings配置文件里面的USE_TZ = True改为False,就可以查到结果了,以后这个值就改为False,而且就是因为咱们用的mysql数据库才会有这个问题,其他数据库没有这个问题。
    

    当查询日期出现问题时:

    将settings.py中最下面的USE_TZ = False改为True

    USE_TZ = True
    

    不是跨时区的应用,不需要考虑时区问题,就将这个值改为False,mysql是对时区不敏感,django往mysql里面出数据的时候,如果这里的值为True,那么将让mysql强制使用UTC时间,那么我们存储进入的时间,当你查询的时候,你就会发现,时间晚了8小时,也就是说你存时间的时候被改为了UTC时间,本地是东八区,比UTC时间多8小时


    3.修改表记录

    update只能是QuerySet类型才能调用,model对象不能直接调用更新方法,所以使用get方法获取对象的时候是不能使用update方法的

    Book.objects.filter(title__startswith="复活").update(price=12)
    

    注意:

    <input type="date" class="form-control" id="book_pub_date" placeholder="出版日期" name="book_pub_date" value="{{ edit_obj.pub_date|date:'Y-m-d' }}">
    

    type='date'的input标签,value的值必须是'Y-m-d'的格式,这个标签才能认识并被赋值,所以,要通过date过滤给它改变格式。


    4.删除表记录

    删除方法.delete()的调用者可以是一个model对象,也可以是一个queryset集合.它运行时立即删除对象而不返回任何值,也可以一次删除多个对象.每个queryset都有一个delete()方法

    models.Book.objects.filter(title='复活').delete()  # 删除标题为复活的Book对象
    

    任何情况下,QuerySet中的delete()方法都只使用一条SQL语句一次性删除所有对象,而并不是分别删除诶个对象,如果想使用model中自定义的delete()方法,就要自行调用每个对象的delete()方法(例如,遍历 QuerySet,在每个对象上调用 delete()方法),而不是使用 QuerySet 中的 delete()方法。

    在Django删除对象时,会模仿SQL约束 ON DELETE CASCDE的行为(删除一个对象时也会删除与它相关联的外键对象)

    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()
    

    delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

    Entry.objects.all().delete()
    
  • 相关阅读:
    Unity3D使用OpenFileDialog后崩溃
    JS定时器
    如果把我剥得一文不名丢在沙漠的中央,只要一行驼队经过———我就可以重建整个商业帝国
    软件开发架构
    C#对象序列化与反序列化
    我的作品们
    fread 不能读取最后一个数据块
    for循环中的i++和++i
    MOS管不能关断的原因!!!
    AD16 快速原理图封装导出
  • 原文地址:https://www.cnblogs.com/robertx/p/10458336.html
Copyright © 2011-2022 走看看