ORM的使用
  1. 什么是ORM
    是一种编程的方法论(模型),与语言无关
  2. ORM的本质:
    类 --> 数据库表
    对象 --> 数据行
    属性 --> 字段
  3.ORM的功能:
    ORM操作数据表
    ORM操作数据行
  4.Django里的ORM的使用
    1.手动创建数据库
    2.在settings.py里面配置数据库的连接信息
    3.在项目init文件中告诉pymsql模块代替Mysqldb来连接mysql数据库
      import pymysql
      pymsql.install_as_MySQLdb()
    4.在app/models.py里面定义类,字段和属性
    5.执行两个命令
      1. python manage.py makemigrations -->将models的类映射成一个文件
      2,python manage.py migrate -->把映射的文件翻译成SQL语句去数据库执行ORM操作
      1.常用的操作方法
            1.返回QuerySet对象
                  1.  all()
                  2.  filter()
                  3.  values()
                  4.  values_list()
                  5.  exclude()
                  6.  order_by()
                  7.  reverse()
                  8.  distinct()
            2.返回具体对象的
                  1.  get()
                  2.  first()
                  3.  last()
            3.返回一个布尔值
                  1.  exists()
            4.返回具体数值
                  1.  count()
      2.单表查询的双下划线
            1. models.Book.objects.filter(id=1)
            2. models.Book.objects,filter(id__gt=1)
            3. models.Book.objects.filter(id__in=[1,2,3])
            4. models.Book.objects.filter(id__range=[1,5])
            5. models.Book.objects.filter(title__contains='沙河') #区分大小写
            6. models.Book.objects.filter(title__icontains='沙河')    #不区分大小写
            7. models.Book.objects.filter(title__startwith='沙河')
            8. models.Book.objects.filter(title__endwith='沙河')
            9. models.Book.objects.filter(publisher_date__year=2017)
            10.models.Book.objects.filter(publisher-date__month=2)
      3.外键的跨表查询
            1.正向查找
                  1. 基于对象
                        book_obj = models.Boo.objects.get(id=1)
                        book_obj.publisher.name
                  2. 基于双下划线的
                        models.Book.objects.filter(id=1).values('publisher__name')
            2.反向查找
                  1.基于对象
                        publisher_obj = models.Publisher.objects.get(id=1)
                        默认反向查找的时候是表名_set
                            publisher_obj.book_set.all()
                        如果在外键中设置了related_name='books'
                            publisher_obj.books.all()
                  2.基于双下划线
                        models.Publisher.objects.filter(id=1).values('book__title')
                        如果配置了related_name='books'
                        models.Publisher.objects.filter(id=1).values('books_title')
      4.分组和聚合
            1.聚合
                  from django.db.models import Avg,Sum,Max,Min,Count
                  models.Book.objects.all().aggregate(Avg('price'))
            2.分组
                  book_list = models.Book.objects.all().annotate(author_num=Count('author'))
      5.F和Q
            1.F(当出现两个字段(可以是相同的字段)进行比较在括号内的时候)
                  查询评论数大于收藏数的书籍
                  from django.db.models import F
                  models.Book.objects.filter(commnet_num__gt=F('keep_num'))
            2.Q(filter等方法中的关键字参数查询都是一起进行“AND” 的,如果涉及到与或非的话使用Q对象)
                  查询出版年份是2017或2018,书名中带物语的所有书。
                  models.Book.objects.filter(Q(publish_date__year=2018)
                        | Q(publish_date__year=2017), title__icontains="物语")
      6. 事务(保证数据的原子性操作)
            from django.db import transaction
            with transaction.atomic():  (当出现错误的时候会回滚事务)
                  new_publisher = models.Publisher.objects.create(name="火星出版社")
                  models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10)  # 指定一个不存在的出版社id
            except Exception as e:
                  print(str(e))
      7.  原生的SQL在ORM
            from django.db import connection, connections
            cursor = connection.cursor()  # cursor = connections['default'].cursor()
            cursor.execute("""SELECT * from auth_user where id = %s""", [1])
            ret = cursor.fetchone()
2.ORM一对一
       1.什么时候用一对一?
              当一张表的某一些字段插叙你的比较频繁的时候,另外一些字段查询的不是特别频繁
              把不怎么常用的字段,单独拿出来做成一张表,然后用过一对一关联起来
       2.优势
              既保证了数据都完整的保存下来,又能保证大部分的检索更快
       3.ORM中的用法
              OneToOneField(to="")
    3.ORM多对多
          多对多的方式
           1.ORM自动帮我创建第三张表
           2.自己创建第三张表,利用外键分别关联作者和书
                  关联查询比较麻烦,因为没办法使用ORM提供的便利方法
           3.自己创建第三张表,注意参数不能调换位置
              使用ORM的ManyToManyField(to="",through="Author2Book", through_fields=("author","book"))
                  add() remove()都是使用不了
       怎么使用
            1.如果第三张表没有额外的字段,就用第一种
            2.如果第三张表有额外的字段,就用第三种或第一种 4.跨站请求伪造
    {% crsf_token %}    #在form表单添加这个自动校验-->生成一个加密的input框