在学习Django时,总感觉这部分内容与实际应用有一定的差异或距离。一方面,Django自带的ORM是一个对底层数据库的适应性很强的组件。不需要强依赖某个数据库,比如sqlite、MySQL、Oracle、PG等,需要一定的学习量。循环。另一方面,因为这个方法是一个通用的API,所以一下子没有SQL语句。理解和接受这个想法需要一点时间,许多DBA需要习惯它。第三点是没有掌握。好像明白了,但是真正写起来的时候,发现自己还是一头雾水,不知从何下手。于是我换个思路,从数据库的角度逆向分析了Django是如何完成我们常见的数据需求的。先做减法,重点放在查询部分。常见的数据需求,这个需求有点大,怎么让它更通用,我想到了oracle中的emp,dept,自学数据库,很多测试用例都离不开这两个表,所以我们从这个作为入口点一步步分析。有些同学可能一开始就退缩了。Oracle需要转换语句和数据类型,使用的数据库是MySQL。是不是有点麻烦?其实这些都不是东西。报酬。我们配置emp和dept的结构,可以在Django的models.py文件中配置。fromdjango.dbimportmodelsimportdjango.utils.timezoneastimezoneclassdept(models.Model):deptno=models.AutoField(primary_key=True)dname=models.CharField(max_length=30)loc=models.CharField(max_length=30,default='')classMeta:db_table='dept'verbose_name='DEPT'verbose_name_plural='DEPT'ordering=['deptno']def__unicode__(self):return'%s%s'%(self.deptno,self.dname)classdept(models.Model):deptno=models.AutoField(primary_key=True)dname=models.CharField(max_length=30)loc=models.CharField(max_length=30,default='')classMeta:db_table='dept'verbose_name='DEPT'verbose_name_plural='DEPT'ordering=['deptno']def__unicode__(self):return'%s%s'%(self.deptno,self.dname)classemp(models.Model):empno=models.AutoField(primary_key=True)ename=models.CharField(max_length=30)job=models.CharField(max_length=30)mgr=models.IntegerField()hiredate=models.DateTimeField('hiredate',default=timezone.now)sal=models.IntegerField()通讯=models.IntegerFielddeptno=models.ForeignKey('dept')类元:db_table='emp'verbose_name='EMP'verbose_name_plural='EMP'verbose_name_plural='EMP'ordering=['empno','ename']def__unicode__(self):return'%s%s'%(self.empno,self.ename)其实看内容不难,类型是通用的使用pythonmanage.pymakemigrations获取更改后的结构和数据Migrationsfor'scott':0001_initial.py:-Createmodeldept-Createmodelemp得到的SQL如下:>pythonmanage.pysqlmigratescott0001BEGIN;CREATETABLE"dept"("deptno"integerNOTNULLPRIMARYKEYAUTOINCREMENT,"dname"varchar(30)NOTNULL,"loc"varchar(30)NOTNULL;CREATETABLE"emp"("empno"integerNOTNULLPRIMARYKEYAUTOINCREMENT,"ename"varchar(30)NOTNULL,"job"varchar(30)NOTNULL,"mgr"integerNOTNULL,"hiredate"datetimeNOTNULL,"sal"integerNOTNULL,"deptno_id"integerNOTNULLREFERENCES"dept"("deptno"));CREATEINDEX"emp_d6b13549"ON"emp"("deptno_id");COMMIT;简单确认后,我们就可以生成创建这两个Table了,使用pythonmanage.pymigrate即可。emp的表结构如下:dept的表结构如下:我们来初始化数据。这时候也可以直接使用SQL。dept表的初始化语句如下:insertintodeptvalues(10,'ACCOUNTING','NEWYORK');insertintodeptvalues(20,'RESEARCH','DALLAS');insertintodeptvalues(30,'SALES','CHICAGO');insertintodeptvalues(40,“操作”,“波士顿”);emp表的初始化语句如下,特别注意字段不是deptno,而是deptno_idinsertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7369,'SMITH','CLERK',7902,'1980-12-17',800.00,20);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7499,'ALLEN','SALESMAN',7698,'1981-2-20',1600.00,30);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7521,'WARD','SALESMAN',7698,'1981-2-22',1250.00,30);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7566,'JONES','MANAGER',7839,'1981-4-2',2975.00,20);inserttintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7654,'MARTIN','SALESMAN',7698,'1981-9-28',1250.00,30);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7698,'BLAKE','MANAGER',7839,'1981-5-1',2850.00,30);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7782,'CLARK','MANAGER',7839,'1981-6-9',2450.00,10);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7788,'SCOTT','ANALYST',7566,'1987--4-19',3000.00,20);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7839,'KING','PRESIDENT',0,'1981-11-17',5000.00,10);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7844,'TURNER','SALESMAN',7698,'1981-9-8',1500.00,30);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7876,'ADAMS','CLERK',7788,'1987-5-23',1100.00,20);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7900,'JAMES','CLERK',7698,'1981-12-3',950,30);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7902,'FORD','ANALYST',7566,'1981-12-3',3000,20);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)values(7934,'MILLER','CLERK',7782,'1982-1-23',1300,10);insertintoemp(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,DEPTNO_ID)值(9999,'SHUNPING','CLERK',7782,'1988-5-5',2456.34,10);剩下的就是实践了,我们选择emp,dept一些常用的SQL,看看ORM能不能完成这个任务。1、显示所有姓名、工种、工资奖金,并按工种降序排列。如果工种相同,则按薪资升序排列。如果使用MySQL,语句和数据结果如下:mysql>selectename,job,salfomemmporderbyjobdesc,salasc;+---------+------------+------+|ename|job|sal|+--------+----------+------+|WARD|SALESMAN|1250||MARTIN|SALESMAN|1250|用order_by方法处理,可以看到有点头绪了,但是还是没有满足要求。>>>emp.objects.all().order_by('job')[
