django模型系统(一)

本文转载自https://blog.csdn.net/xiaogeldx/article/details/87899499

django的orm简介

  • 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
  • orm的优势:用面向对象的方式描述数据库,操作数据库,不用直接编写sql代码,只需像操作对象一样从数据库操作数据

django的orm系统的分析

  • orm系统的方法-(封装)-Python代码-(执行)-sql语句-(操作)-数据库

django模型映射关系

  • 模型类必须都写在app下的models.py文件中
  • 模型如果需要映射到数据库,所在的app必须被安装
  • 一个数据表对应一个模型类,表中的字段对应模型中的类属性,一个实例对应数据表中的一条数据

数据库连接配置

  • django不光支持mysql,一些流行的数据库都支持

django连接MySQL的配置流程

  • 安装pymysql:pip install pymysql

  • 创建数据库用户(有数据库权限的用户)

  • 创建数据库(我的是django_test)

  • 修改配置(settings.py)

      DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',
              'NAME': 'django_test',
              'USER':'xiaoge',
              'PASSWORD':'*****',
              'HOST':'127.0.0.1',
              'PORT':'****'
          }
      }
    
  • 修改项目文件夹(和settings.py文件所在的目录)下的__init__.py添加代码:

      import pymysql
      pymysql.install_as_MySQLdb()
    
  • 设置时区(settings.py)

      TIME_ZONE = 'Asia/ShangHai'	#北京时间
    

模型的创建与映射

创建模型

  • 创建一个student的模型,代表学生

  • 每一个模型都是django.db.models.Model的子类

  • 类变量表示模型中的数据库字段

  • 每一个字段由一个字段类的实例表示

  • 数据表的名称就是模型的名称

  • 在students中的models.py文件中创建模型

      from django.db import models
      class Student(models.Model):     #继承
      	#可以不写主键,模型会创建
      	# id = models.IntegerField(primary_key=True,auto_created=True)  
          name = models.CharField(max_length=20)	#字符串
          age = models.SmallIntegerField(default=0)   #整数,默认为0,表示没填
          sex = models.SmallIntegerField(default=1)   #整数,默认为1(男)
          qq = models.CharField(max_length=20,default='') #字符串,默认不填
          phone = models.CharField(max_length=20,default='')  #字符串,默认不填
          c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)   #创建时间,自动记录当前时间
              def __str__(self):
     				return '%s-%s' % (self.name,self.age)
    

激活模型

  • 在项目中注册app

    • 在settings.py的INSTALLED_APPS中注册
  • 运行数据库迁移命令(在项目根目录下)
    python manage.py makemigrations students#如果不加students,settings.py的INSTALLED_APPS中所有的app都会迁移

    • 告诉django我们做了哪些数据库的修改
      数据库迁移文件见下图的0001_initial.py,再修改就会多个0002
      在这里插入图片描述
    • python manage.py sqlmigrate students 0001可以从迁移的地方获取sql语句,效果见下图
      在这里插入图片描述
    • 表名:appname_模型name(小写的),如students_student
    • django会自动创建主键,一般取名为id
  • 此时数据库中还没有表,需要运行migrate命令使迁移生效

      python manage.py migrate students
    

在这里插入图片描述
- 要修改数据库,都要修改模型,然后运行数据库迁移命令,再运行使迁移生效命令

数据的增删改查

  • django shell调试工具

      python manage.py shell
    
  • 导入模型

      from students.models import Student 
    

In [2]: Student.objects    #模型管理器,每个模型都有一个管理器,通过管理器操作模型                                                                                                            
Out[2]: <django.db.models.manager.Manager at 0x7f7b39787b00>
In [3]: Student.objects.all()                                                                                                          
Out[3]: <QuerySet [ ]>		#查询集
In [4]: s1 = Student(name='xiaoge',age=16,qq='234552')   	#增方法1                                                                              
In [5]: Student.objects.all()                                                                                                          
Out[5]: <QuerySet []>	#此时还没有写进数据库
In [6]: s1.save()  #经过这步才写进数据库                                                                                                                    
In [7]: Student.objects.all()                                                                                                          
Out[7]: <QuerySet [<Student: Student object (1)>]>
In [11]: s2 = Student()         #增方法2 11-14步    依次添加                                                                                          
In [12]: s2.name = 'na'                                                                                                                
In [13]: s2.age = 17                                                                                                                   
In [14]: s2.save() 
In [2]: Student.objects.all()                                                                                                          
Out[2]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>]>
In [3]: s = Student.objects.get(id=1)    #单条数据查看                                                                                              
In [4]: s.name                                                                                                                         
Out[4]: 'xiaoge'
In [5]: s.c_time                                                                                                                       
Out[5]: datetime.datetime(2019, 2, 24, 2, 6, 32, 247014, tzinfo=<UTC>)
In [6]: print(s.c_time)                                                                                                                
2019-02-24 02:06:32.247014+00:00
In [7]: Student.objects.create(name='wen',age=25)        #增方法3                                                                            
Out[7]: <Student: wen-25>
In [8]: Student.objects.all()                                                                                                          
Out[8]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>]>
In [9]: s = Student.objects.get_or_create(name='yi')     #增方法4   查找或创建                                                                              
In [10]: s                                                                                                                             
Out[10]: (<Student: yi-0>, True)	#之前没有,新建成功	#返回元组
In [11]: s = Student.objects.get_or_create(name='wen')                                                                                 
In [12]: s                                                                                                                             
Out[12]: (<Student: wen-25>, False)	#之前有,查到的,没新建
In [13]: s[0].name                                                                                                                     
Out[13]: 'wen'
In [14]: s[0].id                                                                                                                       
Out[14]: 3       
  • 在mysql中查看表
    select * from students_student;
    在这里插入图片描述
    • 存在数据库里的时间(c_time)是UTC时间,取出时自动转换设置的时区

  • Student.objects.all()

  • Student.objects.get(pk=1)

  • Student.objects.filter(sex=1)

      In [16]: res = Student.objects.all()     #查1		这时不会操作数据库
      In [15]: Student.objects.all()     	#这时查所有数据,返回QuerySet(查询集)                                                                                                    
      Out[15]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>, <Student: yi-0>]>		QuerySet是惰性的
      In [17]: print(res.query)      #Student.objects.all()背后执行的sql语句                                                                                                        
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time` FROM `students_student`	#select * from students_student
      In [18]: res       #查1   结合16步     返回一个查询集,可以for循环,迭代,切片                                                                                                                    
      Out[18]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>, <Student: yi-0>]>
      In [19]: print(res[1:2].query)      #切片                                                                                                   
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time` FROM `students_student`  LIMIT 1 OFFSET 1
      In [20]: Student.objects.get(id=1)        #	查2    返回查询对象                                                                                             
      Out[20]: <Student: xiaoge-16>
      In [21]: Student.objects.get(name='yi') 	#get一般和主键对应                                                                                               
      Out[21]: <Student: yi-0>
      In [23]: Student.objects.get(pk=1)  	#pk即主键,防止查错主键名                                                                                                   
      Out[23]: <Student: xiaoge-16>
      In [25]: res = Student.objects.filter(sex=1)    #查3	筛选                                                                                       
      In [26]: res                                                                                                                           
      Out[26]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>, <Student: yi-0>]>
      In [28]: print(res.query)                                                                                                              
      SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time` FROM `students_student` WHERE `students_student`.`sex` = 1
    

当get匹配到多条数据时,会报错
在这里插入图片描述

In [30]: s = Student.objects.get(name='xiaoge')                                                                                        
In [31]: s                                                                                                                             
Out[31]: <Student: xiaoge-16>
In [32]: s.age = 15       #改方法1     改一条数据                                                                                                        
In [33]: s.save()                                                                                                                      
In [34]: Student.objects.get(pk=1)                                                                                                     
Out[34]: <Student: xiaoge-15>
In [35]: Student.objects.filter(name='yi').update(age=19)   #改方法2              可以改多条数据                                                         
Out[35]: 1	#成功返回1
In [36]: Student.objects.get(name='yi')                                                                                                
Out[36]: <Student: yi-19>

In [38]: s = Student.objects.get(id=2)       #删一条  38-40步                                                                                          
In [39]: s                                                                                                                             
Out[39]: <Student: na-17>
In [40]: s.delete()                                                                                                                    
Out[40]: (1, {'students.Student': 1})
In [41]: Student.objects.filter(gender=1).delete()  	#可以删多条  	
In [42]: Student.objects.filter(sex=1).delete()                                                                                        
Out[42]: (3, {'students.Student': 3})
原文地址:https://www.cnblogs.com/xiaogeldx/p/10427672.html