Django知识4----models层

一、配置数据库

1.建立项目的数据库

create database blog;(示例:数据库名字是blog)

2.在setting文件中设置DATABASES

 1 DATABASES = {
 2     'default': {
 3         'ENGINE': 'django.db.backends.mysql', # 改成mysql数据库。
 4         'NAME': 'blog',
 5         'USER': 'root',
 6         'PASSWORD': '123',
 7         'HOST': '127.0.0.1',
 8         'PORT': '3306',
 9     }
10 }

3.在应用的__init__.py文件中添加如下两行

作用:告诉django用pymysql模块来操作数据库,不然就会用默认的mysqldb模块来操作数据库了。

1 import pymysql
2 pymysql.install_as_MySQLdb()

4.在应用的models.py 文件中建立表的模型(定义类)

解释:类似一张Book的表,字段是id,title,author,publishDate,price,以及各个字段的类型和约束条件。

1 class Book(models.Model):
2     id = models.AutoField(primary_key=True)
3     title = models.CharField(max_length=32)
4     author = models.CharField(max_length=32)
5     publishDate = models.DateField()
6     price = models.DecimalField(max_digits=6,decimal_places=2)

5.建立了django的modle.py文件后,运行如下两条命令,在数据库中,按照表模型产生数据表

# 定义好模型,然后在终端执行两条命令来生成数据库。
python manage.py makemigrations
  这时其实是在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, python manage.py migrate
  接着执行migrate,这时候才真的把作用到数据库文件,产生对应的表.

二、model基础内容

1.ORM 映射关系

表名  <-------> 类名

字段  <-------> 属性

表记录 <------->类实例对象

2.单表操作

举例:现在有一个书籍的表(类名:Book)

2.1 添加记录、信息

方式一:(用save())
book_obj = models.Book(title='活着',author='yuan',publishDate='2015-10-23',price=23) # id设置了自增,可以不用添加 book_obj.save()

方式二:
current_obj = models.Book.objects.create(title='',author='',.......)
当前的current_obj就是现在新添加的对象,可以做一些操作。

2.2 修改记录、信息

#方式一:(效率高,推荐)
models.Book.objects.filter(id=1).update(title='',author='')  # update()是queryset类型的方法

# 方式二
bool_obj = models.Book.objects.filter(id=0)[0]
book_obj.title ='new_name'
book_obj.save()

2.3 删除记录、信息

1 models.Book.objects.filter(id=id).delete()

2.4 查询记录、信息(重点)

Object与queryset的区别

# Object 指每条记录,是model类的实例对象
# queryset类型,是从数据库中查询到的每个对象的集合,类似列表。[obj1,obj2,obj3]

示例类的模型

#========models.py==========

from django.db import models

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    author = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=6,decimal_places=2)


    def __str__(self):
        return self.title

返回object对象类型的方法

1  models.Book.objects.get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个如果符合筛选条件的对象超过一个或者没有都会抛出错误。

返回QuerySet类型的方法

1 models.Book.objects.all()    查询多有结果 # <QuerySet [<Book: 活着>, <Book: 水浒传>, <Book: 饿了>]>   类设置了__str__方法,

2 models.Book.objects.filter(title='yuan') # 查询满足title='yuan'的数据,返回QuerySet

3 models.Book.objects.exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象

4 models.Book.objects.filter(author='yuan').values('id','title','author')
# 返回结果 <QuerySet [{'id': 1, 'title': '活着', 'author': 'yuan'}, {'id': 6, 'title': '饿了', 'author': 'yuan'}]>

5. models.Book.objects.filter(author='yuan').values_list('id','title','author')

  # 返回结果:<QuerySet [(1, '活着', 'yuan'), (6, '饿了', 'yuan')]>

其他

 1 <6> order_by(*field):      对查询结果排序
 2  
 3 <7> reverse():             对查询结果反向排序
 4  
 5 <8> distinct():            从返回结果中剔除重复纪录
 6  
 7 <10> count():              返回数据库中匹配查询(QuerySet)的对象数量。
 8  
 9 <11> first():              返回第一条记录
10  
11 <12> last():               返回最后一条记录
12  
13 <13> exists():             如果QuerySet包含数据,就返回True,否则返回False

 三、查询表记录

1.查询相关API

<1> all():                 查询所有结果
 
<2> filter(**kwargs):      它包含了与所给筛选条件相匹配的对象
 
<3> get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                           如果符合筛选条件的对象超过一个或者没有都会抛出错误。
 
<5> exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象
 
<4> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                           model的实例化对象,而是一个可迭代的字典序列
 
<9> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
 
<6> order_by(*field):      对查询结果排序
 
<7> reverse():             对查询结果反向排序
 
<8> distinct():            从返回结果中剔除重复纪录
 
<10> count():              返回数据库中匹配查询(QuerySet)的对象数量。
 
<11> first():              返回第一条记录
 
<12> last():               返回最后一条记录
 
<13> exists():             如果QuerySet包含数据,就返回True,否则返回False

2.基于对象的跨表查询

 1 # ============基于对象的跨表查询============
 2     # 1.一对多关系
 3     # 查询id=1的书籍的出版社所在的城市<br>
 4     book_obj = models.Book.objects.filter(id=1).first()
 5     ret = book_obj.publish.addr   # book_obj.publish 拿到与这本书籍关联出版社的对象
 6 
 7     # 查询 人民出版社出版过的所有书籍
 8     publish_obj = models.Publish.objects.filter(name='清华出版社').first()
 9     ret = publish_obj.book_set.all()  # 反向查询,拿到书籍对象的集合
10 
11     # 2.一对一查询
12     # 查询egon作者的手机号
13     author_obj = models.Author.objects.filter(name='egon').first()
14     ret = author_obj.author_detail.tel
15 
16     # 查询所有住址在北京的作者的姓名 (反向查询)
17     # author_detail_obj = models.Author_detail.objects.filter(addr='北京')  # 返回queryset类型
18     # for each in author_detail_obj:
19     #     print(each.author.name)
20 
21 
22     # 3.多对多查询
23     # 红楼梦所有作者的名字以及手机号
24     # book_obj = models.Book.objects.filter(title='红楼梦').first()
25     # author_list = book_obj.author.all()  # 拿到目前book对象关联的author对象的集合
26     # for each_author in author_list:
27     #     print(each_author.name,each_author.author_detail.tel)
28 
29     # 查询egon出过的所有书籍的名字
30     # author_obj = models.Author.objects.filter(name='egon').first()
31     # book_list = author_obj.book_set.all()  # queryset类型,反向查询拿到egon相关联的book对象
32     # for each in book_list:
33     #     print(each.title)

3.基于双下划线的跨表查询

 1 # ==================基于双下划线的跨表查询==============
 2 
 3     # 1.查询清华出版社出版过的所有书籍的名字与价格(一对多)
 4     # 正向查询 按字段:publish
 5     ret = models.Book.objects.filter(publish__name='清华出版社').values_list('title','price')
 6 
 7     # 反向查询:按表名: book
 8     ret = models.Publish.objects.filter(name='清华出版社').values_list('book__title','book__price')
 9 
10 
11     # 2.查询egon出过的所有书籍的名字(多对多)
12     # 正向查询,按照字段author字段
13     ret = models.Book.objects.filter(author__name='egon').values_list('title')
14 
15     # 反向查询    按表名: book
16     models.Author.objects.filter(name='egon').values_list('book__title')
17 
18 
19     # 3.查询清华出版社出版过的所有书籍的名字以及作者的姓名
20     # 正向查询
21     ret = models.Book.objects.filter(publish__name='清华出版社').values_list('title','author__name')
22     # print(ret)
23     # 反向查询
24     ret = models.Publish.objects.filter(name='清华出版社').values_list('book__title','book__author__name')
25     # print(ret)
26 
27 
28     # 4.手机号以123开头的作者出版过的所有书籍名称以及出版社名称
29     ret = models.Book.objects.filter(author__author_detail__tel__startswith=123).values_list('title','publish__name')
30     # print(ret)

4.聚合查询

 1 # ===============聚合查询=================
 2     from django.db.models import Avg,Max,Min,Count
 3     # queryset.aggregate()
 4 
 5     # 1.单个聚合查询
 6     ret = models.Book.objects.all().aggregate(c = Avg('price'))
 7     # print(ret)
 8 
 9     # 2.多个聚合查询
10     ret = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'))
11     # print(ret)  # 结果:{'price__avg': 31.2, 'price__max': Decimal('55.00'), 'price__min': Decimal('13.00')}

5.分组查询

 1 # 分组查询
 2     # 为QuerySet中每一个对象都生成一个独立的汇总值。
 3     # 1.统计每一本书的作者个数
 4     # 用法:queryset.annotate(),返回的还是queryset类型
 5     ret = models.Book.objects.all().annotate(author_num=Count('author'))
 6     for each_obj in ret:
 7         print(each_obj.title,each_obj.author_num)
 8 
 9 
10     # 2.统计每个出版社的最便宜的书
11     ret = models.Book.objects.values('publish__name').annotate(book_num=Count('title'))
12     # print(ret)

6. F、Q查询

 1     # ==============F、Q查询=================
 2     from django.db.models import F,Q
 3 
 4     # 查询readNum大于wordsNum的书
 5     ret = models.Book.objects.filter(readNum__gt=F("wordsNum")*1.5)
 6     # print(ret)
 7 
 8     # 修改操作也可以使用F函数, 比如将每一本书的价格提高30元
 9     models.Book.objects.all().update(price=F("price")+30)
10 
11     # Q查询
12     ret = models.Book.objects.filter(Q(author__name='yuan')|Q(author__name='egon'))
13     print(ret)
14     ret = models.Book.objects.filter(Q(author__name='yuan')|Q(author__name='egon')).distinct()
15     print(ret)
16 
17     return HttpResponse("OK")

 

原文地址:https://www.cnblogs.com/fengqing89/p/7737077.html