Django framework 08- basics table and multi-table queries related objects

1. Create a self-defined primary key field AutoFiled (pirmary_key = True) # generally not custom, int type, since growth is generally not a custom primary key.

2.order_by asc desc

from django.db.models.function import Lower

res = Student.objects.order_by(Lower('name').desc())

  1. Create table relationships

  • The OneToOne Student = models.OneToOneField ( 'Student', on_delete = models.CASCADE) # associated with the string table under normal circumstances, can not be read to prevent the Student class.

  • OneToMany grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)

  • ManyToMany

  • class Cousrse(models.Model):

    • name = models.CharField ( 'program name', max_length = 20)

    • students = models.ManyToMany ( 'Student') automatically create the third table.

  1. Association table data manipulation

  • OneToMany

  • Forward: A model If a foreign key field is defined by the foreign key operation model CRUD

  • Reverse CRUD

-Many-to-Many specifies the middle of the table, add, remove, set does not work, you must use the middle of the table -One-to-One

  1. Cross-table query

1. Relationship to achieve five associated tables on classroom 2. Case on classroom practice

Operation in the data table:

 

The IDLE project directory:

In order to facilitate learning, we enter the idle project to carry out our operations,

By python manage.py shell can enter IDLE in the current directory

 

1. Go IDLE

2. Check the current directory path

3. Import the model classes we project

Operating data table:

1. First add data to the data in the department table.

 

 

2. View the table structure of the data table student.

 

department_id field is a foreign key field in the department table d_id

To-many relationships between tables of data to add:

3. adding to the data table student data in the first embodiment

 

s = Students()

In [6]: s.name = 'stone detail Qi'

In [7]: g1 = Grade.objects.first()

In [8]: g1 Out[8]: <Grade: Grade object (1)>

In [10]: s.grade = g1

In [11]: s.grade Out[11]: <Grade: Grade object (1)>

In [13]: s.save()

In [14]: s.grade Out[14]: <Grade: Grade object (1)>

Data in Table 4. To add a second embodiment student data

 

s1 = Student(name='二')

g2 = Grade.objects.last()

se.grade_id = g2.id

s2.save

这两种方式的效果是一样的.

 

1.第一种方式就是跟之前的一样,用传参的方法添加,需要注意的是外键的值必须是关联表中已经存在的值.

2.第二种方式是用的属性赋值的方式,因为我们在模型类有定义了一个department的属性,而这个属性的对象的类型必须是department表的类实例对象

删除:s2.grade = None

s2.save()

查:

s2.grade.name

s2.grade.num

表关联对象的访问:

 

Student的模型类中我们有定义department的属性,所以当我们去访问的时候,可以直接通过student.department的形式去找到某个学生的所属学院是哪个.

那么如果我们也希望在在访问某个学院的实现对象的学生的时候改怎么访问呢???

如果模型I有一个ForeignKey,那么该ForeignKey 所指的模型II实例可以通过一个管理器回前面有ForeignKey的模型I的所有实例。默认情况下,这个管理器的名字为foo_set,其中foo 是源模型的小写名称。

例子:g3.students_set <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x7f097b7a0b70>

g3.students_set.create(name='王五') 反向增加.

g3.students_set.add(s) #直接加入一个s对象

create,add,立刻马上操作数据库,add可以加多个

 

可以在定义时设置related_name 参数来覆盖foo_set 的名称.

 

添加了related_name的参数后,重新打开一个IDLE,

访问时就能直接用设置的参数作为属性了.

 

 

处理关联对象的一些方法:

add(obj1, obj2, ...) 添加的已经存在数据库的数据

添加一指定的模型对象到关联的对象集中。

1.d1.student的管理器有add的方法.

2.例子中的s2能添加成功是因为设置了student表中department字段允许为空了.

 

create(\kwargs) 添加不存在的数据 ,将数据直接存入数据库

创建一个新的对象,将它保存并放在关联的对象集返回新创建的对象。

 

remove(obj1, obj2, ...)

从关联的对象集中删除指定的模型对象。

删除的是关系表中的数据

 

因为我们有修改student表中的department_id字段允许为空,所以当删除的时候这个字段值为NULL.删除字段必须设置null为True

clear() 从关联的对象集中删除所有的对象

remove,clear是立刻马上执行.

g3.student_set.set([s,s2])

set方法先调用clear,然后添加

 

注意对于所有类型的关联字段,add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

多表查询----跨关联关系的查询:

Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段:

例子:Students.objectt.filter(grade__name='django框架') #此sql语句用内连接完成查询.

查询学院名字为‘计算机学院’的学生的信息

Student.objects.filter(department__d_name='计算机学院')

它还可以反向工作。若要引用一个“反向”的关系,只需要使用该模型的小写的名称。

查询学生名字中包含 '小' 的学生的学院信息

Department.objects.filter(students_namecontains='小')

查询学号为1的学生所有的课程

Course.objects.filter(student__s_id=1)

查询报了课程1的所有的学生

Student.objects.filter(course__c_id=1)

查询报了'python'课程的的学生的所属学院的信息

Department.objects.filter(student--course--c_name='python')

ManyToMany

add,set,remove都是我们没有指定中间表时候使用.

只要是反向,就用模型的小写加--set.

ManyToManyField相当于一个管理器:

例子:c1.students.all()

通过ManyToManyField字段的介入,就可以不需要中间表进行查询.

OneToOne反向查询中不需要set,直接通过模型的小写调用一个对象,不是管理器.

例子:s1.studentdetail.college

查询性别为1的学生选择的课程

res = Course.objects.filter(students__sex=1)

查询选择python课程的学生:

Students.objects.filter(course--name--counatins='python')

查询选择了英语33期的学生

res = Students.objects.filter(course--name--contains='english',grade--num--contains='33')

查询报名学费小于3000的学生

Students.objects.filter(enroll--pay--lt=3000)

查询报名了python的学生所在的年级

Grade.objects.filter(student--course--name--contains='python')

在执行makemigrations的时候,django自动在数据库中创建一个django-migrations表,记录执行的迁移文件名,如果手动删除了迁移文件,再执行makemigrations时,生成的相同的迁移文件名不会执行.所以还要手动在django-migrations表中手动删除同名记录,才能执行migrate.但是数据库没有相应的回调,执行时会报错.

迁移回滚

python manage.py migrate teacher 0001 #最后是以前版本的迁移文件名

Students.objects.only('name') ,返回的是一个对象列表,可以索引取其他属性,提高效率.only查询id和name,再查询其他属性时又执行查询数据库.

Students.objects.values('name') ,返回的是一个QuerySet,只能索引取到name字典对象,不可以索引取其他属性

左连接查询的一个例子:

res = Students.object.values('name','grade--name') #左连接查询表的年级

Guess you like

Origin www.cnblogs.com/winfun/p/10966828.html