对象  关系  模型

wusir博客地址orm官网API总结

django官网orm-API

orm概要:

ORM 跨表查询
class Book(models.Model):
title = models.CharField( max_length=32) publish=models.ForeignKey(to="Publish",to_field="id")
authors=models.ManyToManyField(to='Author',related_name='bookList')  class Publish(models.Model):
name=models.CharField( max_length=32) class Author(models.Model):
name=models.CharField( max_length=32)
ad=models.OneToOneField("AuthorDetail") class AuthorDetail(models.Model): telephone=models.BigIntegerField() 基于对象查询(sql:子查询) 一对多的关系 (Publish--Book)
正向查询,按字段: 查询python这本书的出版社所在的名称
book_obj=Book.objects.filter(title="python").first()
#print(book_obj.publish.name) 反向查询,按表名小写_set: 人民出版社出版过的所有书籍名称 publish_obj=Publish.objects.filter(name="人民出版社出版").first()
print(publish_obj.book_set.all())
for obj in publish_obj.book_set.all():
print(obj.title) 多对多的关系
正向查询,按字段:
python这本书所有作者的名字
book_obj=Book.objects.filter(title="python").first()
book_obj.authors.all() 反向查询,按表名小写_set:
alex出版过的所有书籍名称
alex=Author.objects.filter(name="alex").first()
alex.bookList.all() 一对一的关系
正向查询,按字段:
查询alex的手机号
alex=Author.objects.filter(name="alex").first()
alex.ad.telephone 反向查询:按表名小写
以151开头的手机号的作者的名字
ad=AuthorDetail.objects.get(telephone__startswith="")
ad.author.name 基于Queryset和 __(sql:join语句): 正向查询,按字段
反向查询,按表名小写 一对多的关系 (Publish--Book) 查询python这本书的所在出版社的名称
Book.objects.filter(title="python").values("publish__name")
for obj in Book.objects.filter(title="python"):
temp={}
temp["publish__name"]=obj.publish.name 人民出版社出版过的所有书籍名称
Publish.objects.filter(name="人民出版社出版").values("book__title") 多对多的关系 python这本书所有作者的名字
Book.objects.filter(title="python").values("authors__name") alex出版过的所有书籍名称
Author.objects.filter(name="alex").values("book__title") 一对一的关系 查询alex的手机号
Author.objects.filter(name="alex").values("ad__telephone") 以151开头的手机号的作者的名字
AuthorDetail.objects.filter(telephone__startswith="").values("author__name") 扩展:
练习1:
查询python这本书的所在出版社的名称
Book.objects.filter(title="python").values("publish__name")
Publish.objects.filter(book__title="python").values("name") 练习2:
手机号以151开头的作者出版过的所有书籍名称以及出版社名称 Book.objects.filter(authors__ad__telephone__startswith="").values("title","publish__name") 分组查询: 查询每一个出版社出版过的书籍个数 Publish.objects.annotate(Count("book__id")) select count(*) from publish group by id SELECT "app01_publish"."name", COUNT("app01_book"."id") AS "c" FROM "app01_publish" LEFT OUTER JOIN "app01_book" ON ("app01_publish"."id" = "app01_book"."publish_id") GROUP BY "app01_publish"."id", "app01_publish"."name" publish: book: id name id title publish_id
1 A 1 python 1
2 B 2 go 1
3 C 3 linux 2
4 php 3
5 java 3 publish-book: nid publish_id publish_name book_id book_title publish_id
1 1 A 1 python 1
2 1 A 2 go 1
3 2 B 3 linux 2
4 3 C 4 php 3
5 3 C 5 java 3

多对一/一对多,

多对多{类中的定义方法}

三种方式建表

day69

1. 昨日内容回顾

    1. 单表增删改查
2. 单表查询API
返回QuerySet对象的:
1. .all()
2. .filter()
3. .values()
4. .values_list()
5. .exclude()
6. .order_by()
7. .reverse()
8. .distinct() 返回单个数据对象:
1. .first()
2. .last()
3. .get() 返回布尔值的:
1. .exists()
返回数字的:
1. .count() 3. 神奇的双下划线:
配合filter()来做各种查询。
1. id__gt=1
2. id__lt=3
3. id__in=[1,2,3]
4. id__range=[1,5] 5. name__contains="s"
6. name__icontains="s"
7. name__startwith="a"
8. name__endswith="x" 9. first_day__year="" 10. cname__isnull=True *! 4. Django日志配置 2. 今日内容
表之间的关系 1. 一对多
2. 一对一
如下所示:
class Student(model,Model):
sname = models.CharField(max_length=23,verbose_name='学生姓名)
the_class=models.ForeignKEy(to=Class,to_field='id',
on_delete=models.CASCADE, related_name='students')
detail = models.OneToOneField(to='StudentDetail', null=True) class StudentDetail(models.Model):
hetght=models.PositiveIntegerField()
weitht=models.PositiveIntegerField()
email=models.EmailField() 对应关系:
类 --> 表
类的属性 --> 字段
实例对象 --> 一条数据(数据行) 数据库层面:
外键 对应 另外一个表的一条记录
cid_id
ORM层面:
外键对应 另外一个表的一个对象
student_obj.cid_id --> 具体的值 为什么? Django把关系包装成一个具体的对象
cid
正向查找:
student_obj=models.Student.objects.first()
student_obj.detail.email
反向查找:
默认是表名_set.all()
detail_obj=models.StudentDetail.objects.get(id=1)
detail_obj.student.sname
如果在外键的字段中加了related_name属性,则按照该属性的值来反向查找 3. 多对多
老师 和 班级 通过第三张表关联 Teacher表
id tname 1 Alex
2 Egon
3 yuan Class表 id cname
1 1班
2 2班
3 3班 TeacherToClass id teacher_id class_id
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
6 1 1 多对多三种方式创建表格: 第一种:(没有使用到ManyToMany的格式去创建,使用不到它内部封装好的一些便捷用法,但是可扩展性强便于理解)
class Course(models.Model):
id=models.AutoField(primary_key=True) # 主键
cname=models.CharField(max_length=20) # 班级名称
first_day=models.DateField() # 开班时间 class Teacher(models.Model):
tname=models.CharField(max_length=20) # 自定义三张表格,通过外键去关联上面两张表格
class Teacher2Class(models.Model):
teacher=models.ForeignKey(to='Teacher)
the_class=models.ForeignKey(to='Course') class Meta: # 这里是指定我们的表格里面的这两个字段不可以有重复的,不可以同时出现重复,也就是我们说的联合主键
unique_together=("teacher", 'the_class') 第二种方式:(我们这里只是定义了两个类,course和teacher,没有定义第三个类,但是我们运行程序的时候系统会自动给我们生成第三张表格出来用于建立我们的 多对多的关系,但是注意了,我们上面提到了我们并没有建立第三张表格,它系统给我们生成的,我们不能够对这个自动生成的表格进行操作,这就是不够遍历的地方,优势当然是我们在不适用第三张表格的前提下,另外两张表格的操作会更加便捷)
通过manyToManyField去创建
class Course(models.Model):
id=models.AutoField(primary_key=True)
cname=models.CharField(max_length=20)
first_day=models.DateField() class Teacher(models.Model):
tname=models.CharFirld(max_length=30)
cid=models.ManyToManyField(to='Course,relate_name='teachers) 第三种方式:(优劣自己体会)
通过外键和ManyToManyField创建
class Course(models.Model):
id=models.AutoField(primary_key=True)
cname=models.CharField(max_length=30)
first_day=models.DateField() class Teacher(models.Model):
tname=models.CharField(max_length=40)
# 通过manyToManyField和手动去创建第三张表格
cid=models.ManyToManyField(to='Class',through='Teacher2Class',through_fields=('teacher', 'the_class')) class Teacher2Class(models.Model):
teacher=models.ForeignKey(to='Teacher')
the_class=models.ForeignKey(to='Course') class Meta: # 建立联合主键
unique_together=('teacher', 'the_class') 多对多操作
正向查询(从老师表格查询班级表格)
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.all() # 查询该老师授课的所有班级 反向查询(由班级表格反向查询老师表格)
class_obj=models.Course.objects.first()
class_obj.teachers.all() # 此处用到的是related_name,如果不设置的话就用默认的表名_set 常用方法:
create()
创建一个新的对象,保存对象,并将它添加到关联对象集中,返回新创建的对象
import datetime
teacher_obj.cid.create(cname='num9_class',first_day=datetime.datetime.now()) add()
把指定的models对象添加到关联对象集中
添加对象
class_obj=models.Course.objects.filter(id__lt=3)
models.Teacher.objects.first().cid.add(*class_obj) 添加id
models.Teacher.objects.first().cid.add(*[2,3,5]) set()
更新model对象的关联对象
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.set([2,3,4]) remove()
从关联对象集中移除执行的model对象
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.remove(3) clear()
从关联对象集中移除一切对象
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.clear() 4. 了不起的双下划线:
找学生名字里面带龙字的班级
sname__contains="龙"
models.Class.objects.filter(students__sname__contains="龙")
双下划线表示跨表 3. 今天作业
1. 今天上课的例子要写完,博客整理好 2. 自己设计图书管理系统的表结构,用咱们今天上课学到的内容,做查询的练习 书和作者 多对多
书和出版社 多对一 使用双下划线练习跨表查询

中介模型第三种方式,两头都占上:

class Author(models.Model):
name=... class Book(models.Model):
title=...
authors=models.ManyToManyField("Author") author id name
1 alex
2 egon
3 wu book id title
1 linux
2 python book_authors id book_id author_id 1 2 1
2 2 2
3 2 3 book_obj=Book.objects.create(title="python")
book_obj.authors.all() # 与这本书关联的所有作者对象集合 alex=models.Author.get(name="alex")
egon=models.Author.get(name="egon")
wu=models.Author.get(name="wu") author_list=models.Author.objects.all()
book_obj.authors.add(*[alex,wu,egon])
book_obj.authors.add(*author_list)
book_obj.authors.remove(alex)
book_obj.authors.clear()
book_obj.authors.set() ###################################################### 中介模型: class Student(models.Model):
name=...
courses=models.ManyToManyField("Course",through="Student2Course") class Course(models.Model):
name=... class Student2Course(models.Model):
student=models.ForeignKey("Student")
course=models.ForeignKey("Course")
score=models.IntegerField() 扩展关系表: teacher course student score id student_id course_id score
1 1 1 90
2 1 2 80
3 2 1 80
4 1 3 注意事项: 失效:
alex=Student.objects.get(name="alex")
yuwen=.....
alex.courses.add(yuwen)
how:
Student2Course.objects.create(student_id=1,course_id=3,score=100)

代码级别实现:

from django.db import models

# Create your models here.

一对一关系:

class Class(models.Model):
id = models.AutoField(primary_key=True)
cname = models.CharField(max_length=32, null=True)
first_day = models.DateField() def __str__(self):
return self.cname class Student(models.Model):
id = models.AutoField(primary_key=True)
sname = models.CharField(max_length=32) cid = models.ForeignKey(to="Class", to_field="id", related_name="students") # 表里面:student_obj.cid_id=Class对象.id ; student_obj.cid=Class对象
# detail = models.ForeignKey(to="StudentDetail", unique=True)
detail = models.OneToOneField("StudentDetail", null=True) def __str__(self):
return self.sname class StudentDetail(models.Model):
# id = models.AutoField(primary_key=True)
# 正小整数
height = models.PositiveSmallIntegerField()
email = models.EmailField()
memo = models.CharField(max_length=128, null=True) ================================================================================== # 多对多
# 第一种
# 不能用Django ORM 多对多操作的语法
# class Teacher(models.Model):
# tname = models.CharField(max_length=32)
#
#
# class TeacherToClass(models.Model):
# tid = models.ForeignKey(to="Teacher")
# cid = models.ForeignKey(to="Class")
#
# class Meta:
# unique_together = ("tid", "cid") # 第二种
# 自动创建的第三张表,我没有类和它对应,也就是我不能通过ORM单独操作第三张表
class Teacher(models.Model):
tname = models.CharField(max_length=32)
cid = models.ManyToManyField("Class", null=False) # 第三种
# class Teacher(models.Model):
# tname = models.CharField(max_length=32)
# cid = models.ManyToManyField(to="Class", through="TeacherToClass", through_fields=("tid", "cid"))
#
#
# class TeacherToClass(models.Model):
# tid = models.ForeignKey(to="Teacher")
# cid = models.ForeignKey(to="Class")
#
# class Meta:
# unique_together = ("tid", "cid")

注意的点是我们在关联外键的时候可以直接指定表名即可,不用写上to,然后如果不指定字段的话orm会自动给我们关联到那个表格的id字段上,然后我们建立表格的时候如果不写id字段,不写主键的话,orm会自动给我们生成一个id字段并且自动指定i自动生成的这个id字段为主键

如果设置了related_name="students",反向查询时可直接使用students进行反向查询。

我们的related_name就是相当于我们的url路由设置里面的反向解析的原理,我们在查询数据的时候会用到这个功能,在反向解析里面我们直接使用别名就可以倒推出我们的url地址配置,

在表格关联外键的场景里面也是一样的,我们在查询的时候,通过一个表格去查他的外键的关联表格,

比如我关联你,那么我查询你的时候就是正向查询,而你查询我的话就属于反向查询,在反向查询里面我们就需要使用到了我们自定义的那个related_name值

那么我们的related_name放到哪里呢,

我们的A表格需要关联到B表格的一个字段作为外键,那么我们的related_name参数就放到我们的A表格的需要建立外键的那个字段里面,作为一个参数,以=赋值的形式放进去,要赋值给一个变量,用引号引起来的变量名,如下:

class Student(models.Modes):
sname=models.CharField(max_length=20,verbose_name='学生姓名')
the_class=models.ForeignKey(to=Class, to_field='id', on_delete=models.CASCADE,
related_name='students')
detail=models.OneToOneField(to='StudnetDetail',null=True) class StudentDetail(models.Model):
height=models.PositiveIntegerField()
weight=models.PositiveIntegerField()
email=models.EmailField()

这里我们来针对一对多的具体事例进行一点解析:

<table border="1">
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>学生姓名</th>
<th>所在班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for student in student_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ student.id }}</td>
<td>{{ student.sname }}</td>
<td>{{ student.cid.cname }}</td>
{# 我们这里的student.cid.cname它的场景是我们在student表格里面建立了一个外键cid用它去关联我们的class表格里面的id字段#}
(# 我们这样写就是通过我student的这个外键的设置去找到了我们的class表格里面的cname字段并取到它的值,#)
{# 我们之所以可以这样操作是基于我们的orm里面的语法,通过类去创建表格然后根据类的属性去创建表格里面的字段,使用了面相对象编程的方式,极大地减少了代码的冗余#}
{# 我们的对应关系是 类---表 ;类的属性----字段 ; 实例化的对象---表格里面的一条数据行;#}
<td>
<a href="{% url 'delete_student' student.id %}">删除</a>
{# <a href="{% url 'edit_class' %}?class_id={{ class.id }}">编辑</a>#}
<a href="{% url 'edit_student' student.id %}">编辑</a>
</td>
</tr>
{% endfor %} </tbody>
</table>

上面是前端部分,我们再来看看我们的后端代码是如何实现的,与之对应上,

def student_list(request):

  student_list=models.Student.objects.all()

  return render(request, 'student_list.html',{"student_list": student_list}

具体解析部分:

这里的student是一个类,student_list是一个queryset(查询结果的集合,里面存储了一个或者多个对象),{%for student in student_list %}是从一个queryset中循环取出每个对象

student.cid是取出这一个对象的属性,(也就是类的属性,对应这个数据库中的这个表的字段,请参考上面注释部分的对应关系,),而此时这个cid是一个外键,对应着class那个类[也就是class那个表格]的id(数据库的id字段)对象,所以可以直接通过student.cid.cname去取出class表中对应的那一行数据的cname字段的值,

也就是说我们通过我们自己的表格的名字[student]加上.关联外键的字段名[cid]加上.想要查询的外键表格里面的字段[cname...]就可以实现我们在本表格里面去查找我们所关联外键的那个表格里面的字段.{这就有点类似于死记硬背了,固定格式,.....尽力去理解吧}

一对一

正向查询

student_obj=models.Student.objects.first()

student_obj.detail.email

反向查询:

detail_obj=models.StudentDetail.objects.get(id=2)

detail_obj.student.sname  # 我们一对一的时候反向查询只需要用得到对象.表名就可以拿到我们的结果了

多对多操作

正向查询

teacher_obj=models.Teacher.objects.first()

teacher_obj.cid.all()

反向查询

class_obj=models.Class.objects.first()

class_obj.teachers.all()  # 此处我们设置了related_name,我们的related_name值是teachers,如果我们没有设置它的话就是用使用我们的表格名字Teacher_set.all()去取到所有的值

我们在这里把正向和反向总结一下,我们的一对一关系里面,和一对多的关系里面,要理清一个概念就是我们的关系里面谁要关联谁,这个是关键点,理清了之后我们建立表格的时候谁的字段里面需要添加外键,然后谁就是主动方,然后就可以分清被动方,这样我们顺着思路就可以理清了正向和反向的概念

在多对多关系里面我们无所谓谁关联谁,反正是一样的概念,但是我们依然需要分清正向和反向,正反向涉及到我们后续需要使用的方法,所以,跟上面一样我们的多对关系中,外键设定在谁的表格里面,那么谁就掌握了主动发方,谁就是正向,反之则是反向,所以,一句话总结,我们的一对一关系,一对多关系,多对多关系,都是需要区分正向和反向的.这样我们后续使用查询方法的时候便于区分哪些是正向哪些是反向的.

对于object对象的增删改查方法:

查询:

get()

first()

last()

增加:

obj=models.Author(name="fred",age=29)

obj.save()

删除:

models.AuthorDetail.objects.get(addr="大理").delete()  # 直接使用过滤方式找到那个objects对象,然后使用delete()即可删除

修改:

obj=models.Author.objects.get(id=2)

obj.name="亮晶晶"

obj.save()

=================================================================================================

多对多关系的常用方法:

create()  创建

创建一个新的对象,保存对象,并将它添加到关联对象集中,返回新创建的对象

import datetime

teacher_obj.cid.create(cname='9班',first_day=datetime.datetime.now())

add() 增加

把指定的model对象添加到关联对象集中

添加对象

class_objs=models.Class.objects.filter(id__lt=3)  # 这里使用到了双下线的方法,__lt,小于

models.Teacher.objects.first().cid.add(*class_objs)

添加id

models.Teacher.objects.first().cid.add(*[2,4,3,1])  # 这里需要打散之后一个个添加

book_obj=Book.objects.create(title="python")

author_list=models.Author.objects.all()

book_obj.author.add(*author_list)

book_obj.author.add(*["wusir","alex","pete"])

book_obj.author.add("fred")

set()  # 仅限于多对一或者多对多 修改

更新model对象的关联对象

teacher_obj=models.Teacher.objects.first()

teacher_obj.cid.set([2,1,4,5])

示例:

我们在models里面把表格定义成多对多的关系:

class Course(models.Model):
id = models.AutoField(primary_key=True)
cname = models.CharField(max_length=30)
first_day = models.DateField(null=True) def __str__(self):
return self.cname class Teacher(models.Model):
tname = models.CharField(max_length=20)
cid = models.ManyToManyField(to='Course', related_name='teachers') def __str__(self):
return self.tname
然后我们在演示set效果的时候,这样操作:

from api_app import models

a=models.Teacher.objects.first()  # 我们这里必须要是object对象才可以使用我们的set方法,如果是jqueryset则不具备这个方法,

set的用法就是我们得到一个object对象然后我们通过我们的对象去.关联字段名.set([可迭代数据类型])   # 这里如果是字典的话,我们的修改只是取到了我们的key的值,那么我们的value里面的值就没有意义了,所以没有必要去浪费多余的内存空间,我们一般都是写成列表和元祖还有集合的形式,
a.cid.set(2,3,8)我们的set方法是直接覆盖掉原来的值,不论我们之前有没有值,是什么值,都一刀切,直接替换掉,我们之前写的学生系统的增删改查,

在里面我们的 改 操作,里面包含了很多的可能性,有5种,增加,减少,更改,不更改,还有一个不记得了,总之都是封装到了我们的set用法里面了,
我们的add是直接在原来的基础上进行增加,不做修改,只管增加 update()修改我本张表格的具体数值内容

models.Book.objects.filter(title="自由#$%num one#$%").update(title="自由")  # 这里是queryset的修改方法,对我自己的这张表格的具体数据进行修改,就使用update,

remove()

从关联对象集中移除执行的model对象

teacher_obj=models.Teacher.objects.first()  # 我们先取到这个对象,

teacher_obj.cid.remove(5)  # 然后再移除它

clear()

从关联对象中移除一切对象

teacher_obj=models.Teacher.objects.first()  # 先得到一个对象

teacher_obj.cid.clear()  # 我们再拿这个对象去到它的关联的外键的表格里面去清空那个表格里面的数据

我们在使用remove()或者clear()方法操作的时候,如果我们关联的那个表格---专业术语叫做对象集,对象集为空的话,必须要满足null=True,

也就是说我们如果清空了一组数据,而那组数据又在一开始设定的时候被设定为不能够为空,那么我们的程序是会报错的,你不能够清空一个不可以为空的字段值,也就是类属性,这是矛盾的,系统无法识别你的操作,不会执行操作的

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

这个是老师很潦草的笔记,如果不明白就不建议看它了,如果有比较清晰的对该知识点的理解,可以参考一下,类似于找毛病的作用,如果你能看出他的内容有不严谨的地方,那么你就理解了重点内容

day67

ORM

特殊的语法
一个简单的语法 --翻译成--> SQL语句 语法:
1. 操作数据库表 创建表、删除表、修改表 2. 操作数据库行 增、删、改、查 怎么连数据库:
需要手动创建数据库
手写一段代码
告诉Django连哪个数据库
告诉Django用pymysql代替默认的MySQLdb
发命令:
python manage.py makemigrations
python manage.py migrate 总结详细步骤:
1. 手动创建数据库
2. 在app/models.py里面写上一个类,必须继承models.Model这个类 (注意启动Django项目)
3. 在Django 项目的settings.py 里面 配置上数据库的相关信息
4. 在Django项目里的__init__.py里面写上 两句话 import pymysql pymysql.install_as_MySQLdb()
5. 给Django发布命令
1. python manage.py makemigrations # 相当于去你的models.py 里面看一下有没有改动
2. python manage.py migrate # 把改动翻译成SQL语句,然后去数据库执行 models.py --> Django翻译成SQL --> pymysql --> MySQL(4p) 哪吒老师ORM思想:
五步四部分 目前为止学到的特殊语法之操作数据表部分:
1. 通过建一个类(继承models.Model) --> 相当于创建了一个数据库中的表 --> 类 - 数据表
2. 字段:
1. models.AutoField(primary_key=True) --> int 自增的 主键
2. models.CharField(max_length=32, null=True) --> varchar(32)
3. models.IntegerField() # int 总结一下:
models.py MySQL
类 对应 数据表
类的属性 对应 数据库里面的字段(列)
对象 对应 一行数据(一条数据) ORM到底是什么? 对象关系映射 数据行的操作:
增:两种
1. models.User.objects.create(**{}) 直接创建并且提交到数据库
2. user = models.User(**{}) user.save() 删:
找到对象删除
models.User.objects.filter().delete() 改:
更新 两种
1. models.User.objects.filter().update(username="一枝花")
2. user = models.User.objects.get(id=1) user.username="梁志华" user.save() 查:
models.User.objects.all()
models.User.objects.get(条件) 不满足条件就报错|返回的是一个对象
models.User.objects.filter(条件) 不满足条件不报错,但是返回的结果是一个对象的列表
models.User.objects.filter().first()
models.User.objects.filter().last() models.User.objects.exclude(条件) 3. 今日作业
整理今天的内容 4. 周末作业
班级表和学生表 增删改查 再写一遍(最素的页面) 5. 下周内容
1. ORM版学员管理系统
cookie和session
AJAX(模态框版增删改查)
中间件(有时间)
day68

Django

    安装
创建项目
配置(3个:settings.py:1 模板,2静态文件 3 csrf)
创建APP python manage.py startapp app01
三部分:
urls.py
1. 普通正则
2. 分组正则 url(r'/blog/(\d+)/(\d+)', views.blog) blog(request, arg1, arg2) 传位置参数
3. 分组命名 url(r'/blog/(?P<year>\d+)/(?P<month>\d+)', views.blog) blog(request, year, month) 传关键字参数
4. 用name指定别名 url(r'/blog/(?P<year>\d+)/(?P<month>\d+)', views.blog, name="blog") blog(request, year, month)
涉及到了反向解析URL:
1. HTML里面:{% url ‘blog’ 2017 12 %}
2. views里面:from django.urls import reverse reverse("blog", arg=(2017, 12)) 5. 用namespace指定命名空间
url(r'^app01/', include(app01.urls, namespace="app01")),
url(r'^app02/', include(app02.urls, namespace="app02")) 涉及到了反向解析URL:
1. HTML里面:{% url ‘app01:blog’ 2017 12 %}
2. views里面:from django.urls import reverse reverse("app01:blog", arg=(2017, 12)) views.py
request对象
response对象
FBV和CBV xxx.html 模板语言
{{变量}}
{{变量.}} {% for %}循环
{% if %}判断 过滤器(filter) {{ 变量名|filter_name:参数 }} {{时间对象|date:‘Y-m-d’}}
{% url %}
{% load static %}
{% static "img/1.png" %} 母版、继承、块、组件 连接数据库(ORM) 五步四部分 五步:
1. 创建数据库
2. 在app下的models.py里面创建model类,继承models.Model
3. 在settings.py里面配置数据库连接信息
4. 在项目(project)的__init__.py里面写上 import pymysql, pymysql.install_as_MySQLdb()
5. 发命令:
python manage.py makemigrations 收集变更
python manage.py migrate 翻译成SQL语句,执行
四部分:
1. models.py
2. Django
3. pymysql
4. MySQL ORM:
类 ---> 数据表
类的属性 ---> 数据列(表里的字段)
对象 ---> 数据行 增删改查:
查:
models.类名.objects.all() 取所有
models.类名.objects.get() 取一个, 取不到就报错
models.类名.objects.filter(条件) 根据条件查找,返回的是[object1, objdect2 ...]
models.类名.objects.exclude(条件) 排除满足条件的
models.类名.objects.first()
models.类名.objects.last()
增加:
models.类名.objects.create(name="王永飞", age=18) obj = models.类名(name="王永飞", age=18)
obj.save()
删除:
models.类名.objects.filter(age=18).delete() 修改:
models.类名.objects.filter(age=18).update(name="装嫩") 单个对象不能调用update
obj = models.类名.objects.get(id=2)
obj.name = "一枝花"
obj.save() 引申:
SQLAlchemy Flask 2. 今日内容 单表的增删改查
单表查询的API介绍
13条:
返回的是QuerySet对象:
1. all()
2. filter()
3. exclude()
4. valus()
5. values_list()
6. order_by()
7. reverse()
8. distinct()
返回数字的:
1. count()
返回布尔值的:
1. exists()
返回具体的数据对象的:
1. get()
2. first()
3. last() logging配置参数: LOGGING = {
'version': 1, # 目前为止有且只有这一个值
'disable_existing_loggers': False, # 不禁用已经存在的logger实例
# 定义一些日志的处理方式
'handlers': {
'console': {
'level':'DEBUG', # handle的日志级别
'class':' logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True, # 向上传导
'level':' DEBUG', # logger实例的日志级别
},
}
} 表之间的关系
一对一
一对多
外键通常设置在多的那个表里面
多对多
day69

1. 昨日内容回顾

    1. 单表增删改查
2. 单表查询API
返回QuerySet对象的:
1. .all()
2. .filter()
3. .values()
4. .values_list()
5. .exclude()
6. .order_by()
7. .reverse()
8. .distinct() 返回单个数据对象:
1. .first()
2. .last()
3. .get() 返回布尔值的:
1. .exists()
返回数字的:
1. .count() 3. 神奇的双下划线:
配合filter()来做各种查询。
1. id__gt=1
2. id__lt=3
3. id__in=[1,2,3]
4. id__range=[1,5] 5. name__contains="s"
6. name__icontains="s"
7. name__startwith="a"
8. name__endswith="x" 9. first_day__year="" 10. cname__isnull=True *! 4. Django日志配置 2. 今日内容
表之间的关系 1. 一对多
2. 一对一
如下所示:
class Student(model,Model):
sname = models.CharField(max_length=23,verbose_name='学生姓名)
the_class=models.ForeignKEy(to=Class,to_field='id',
on_delete=models.CASCADE, related_name='students')
detail = models.OneToOneField(to='StudentDetail', null=True) class StudentDetail(models.Model):
hetght=models.PositiveIntegerField()
weitht=models.PositiveIntegerField()
email=models.EmailField() 对应关系:
类 --> 表
类的属性 --> 字段
实例对象 --> 一条数据(数据行) 数据库层面:
外键 对应 另外一个表的一条记录
cid_id
ORM层面:
外键对应 另外一个表的一个对象
student_obj.cid_id --> 具体的值 为什么? Django把关系包装成一个具体的对象
cid
正向查找:
student_obj=models.Student.objects.first()
student_obj.detail.email
反向查找:
默认是表名_set.all()
detail_obj=models.StudentDetail.objects.get(id=1)
detail_obj.student.sname
如果在外键的字段中加了related_name属性,则按照该属性的值来反向查找 3. 多对多
老师 和 班级 通过第三张表关联 Teacher表
id tname 1 Alex
2 Egon
3 yuan Class表 id cname
1 1班
2 2班
3 3班 TeacherToClass id teacher_id class_id
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
6 1 1 多对多三种方式创建表格: 第一种:(没有使用到ManyToMany的格式去创建,使用不到它内部封装好的一些便捷用法,但是可扩展性强便于理解)
class Course(models.Model):
id=models.AutoField(primary_key=True) # 主键
cname=models.CharField(max_length=20) # 班级名称
first_day=models.DateField() # 开班时间 class Teacher(models.Model):
tname=models.CharField(max_length=20) # 自定义三张表格,通过外键去关联上面两张表格
class Teacher2Class(models.Model):
teacher=models.ForeignKey(to='Teacher)
the_class=models.ForeignKey(to='Course') class Meta: # 这里是指定我们的表格里面的这两个字段不可以有重复的,不可以同时出现重复,也就是我们说的联合主键
unique_together=("teacher", 'the_class') 第二种方式:(我们这里只是定义了两个类,course和teacher,没有定义第三个类,但是我们运行程序的时候系统会自动给我们生成第三张表格出来用于建立我们的 多对多的关系,但是注意了,我们上面提到了我们并没有建立第三张表格,它系统给我们生成的,我们不能够对这个自动生成的表格进行操作,这就是不够便利的地方,优势当然是我们在不使用第三张表格的前提下,另外两张表格的操作会更加便捷)
通过manyToManyField去创建
class Course(models.Model):
id=models.AutoField(primary_key=True)
cname=models.CharField(max_length=20)
first_day=models.DateField() class Teacher(models.Model):
tname=models.CharFirld(max_length=30)
cid=models.ManyToManyField(to='Course,relate_name='teachers) 第三种方式:(优劣自己体会)
通过外键和ManyToManyField创建
class Course(models.Model):
id=models.AutoField(primary_key=True)
cname=models.CharField(max_length=30)
first_day=models.DateField() class Teacher(models.Model):
tname=models.CharField(max_length=40)
# 通过manyToManyField和手动去创建第三张表格
cid=models.ManyToManyField(to='Class',through='Teacher2Class',through_fields=('teacher', 'the_class')) class Teacher2Class(models.Model):
teacher=models.ForeignKey(to='Teacher')
the_class=models.ForeignKey(to='Course') class Meta: # 建立联合主键
unique_together=('teacher', 'the_class') 多对多操作
正向查询(从老师表格查询班级表格)
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.all() # 查询该老师授课的所有班级 反向查询(由班级表格反向查询老师表格)
class_obj=models.Course.objects.first()
class_obj.teachers.all() # 此处用到的是related_name,如果不设置的话就用默认的表名_set 常用方法:
create()
创建一个新的对象,保存对象,并将它添加到关联对象集中,返回新创建的对象
import datetime
teacher_obj.cid.create(cname='num9_class',first_day=datetime.datetime.now()) add()
把指定的models对象添加到关联对象集中
添加对象
class_obj=models.Course.objects.filter(id__lt=3)
models.Teacher.objects.first().cid.add(*class_obj) 添加id
models.Teacher.objects.first().cid.add(*[2,3,5]) set()
更新model对象的关联对象
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.set([2,3,4]) remove()
从关联对象集中移除执行的model对象
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.remove(3) clear()
从关联对象集中移除一切对象
teacher_obj=models.Teacher.objects.first()
teacher_obj.cid.clear() 4. 了不起的双下划线:
找学生名字里面带龙字的班级
sname__contains="龙"
models.Class.objects.filter(students__sname__contains="龙")
双下划线表示跨表 3. 今天作业
1. 今天上课的例子要写完,博客整理好 2. 自己设计图书管理系统的表结构,用咱们今天上课学到的内容,做查询的练习 书和作者 多对多
书和出版社 多对一 使用双下划线练习跨表查询

day 69 orm操作之表关系,多对多,多对一(wusir总结官网的API)的更多相关文章

  1. Django框架表关系外键-多对多外键(增删改查)-正反向的概率-多表查询(子查询与联表查询)

    目录 一:表关系外键 1.提前创建表关系 2.目前只剩 书籍表和 书籍作者表没创建信息. 3.增 4.删 5.修改 二:多对多外键增删改查 1.给书籍绑定作者 2.删 3.修改 4.清空 三:正反向的 ...

  2. Django的orm操作之表查询二

    复习 单表查询 # 单表操作 # 增 # 方式1 user_obj=models.User.objects.create(**kwargs) # 之一create # 方式2 user_obj=mod ...

  3. MySQL数据库 字段操作 多表关系(更新中...)

    外键 (foreign key) ## 外键 ```mysql # 作者(author):id,name,sex,age,mobile, detail_id # 作者详情(author_detail) ...

  4. django ORM中的表关系

    多对一: 为了方便理解,两个表之间使用ForeignKey连接时,使用ForeignKey的字段所在的表为从表,被ForeignKey连接的表为主表. 使用场景:书和出版社之间的关系,一本书只能由一个 ...

  5. Hibernate表关系映射之多对多映射

    一.多对多的实现原理 在数据库中实现多对多的关系,必须使用连接表.也就是用一个独立的表来存入两个表的主键字段,通过遍历这张表来获取两表的关联关系. 而在我们的对象中,多对多是通过两者对象类中互相建立对 ...

  6. Django中的表关系实现及操作

    表关系的实现   预备知识 ORM的正向操作和反向操作: 1.正向操作:一个模型中定义了一个外键,通过该模型对该外键操作的操作叫做正向操作. 2.反向操作:被外键所关联的模型,通过该模型对外键所在模型 ...

  7. 5) ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response

    一.前戏要做好 配置:settings.py #注册drf INSTALLED_APPS = [ # ... 'api.apps.ApiConfig', 'rest_framework', ] ​ # ...

  8. Hibernate的多表关系

    多表关系 一对多/多对一 O 对象 一的一方使用集合. 多的一方直接引用一的一方. R 关系型数据库 多的一方使用外键引用一的一方主键. M 映射文件: 一: <set name="& ...

  9. mysql表关系

    表与表之间的关系 """ 把所有数据都存放于一张表的弊端 1.组织结构不清晰 2.浪费硬盘空间 3.扩展性极差 """ # 上述的弊端产生原 ...

随机推荐

  1. mvc 母版页保持不刷新

    //比如这是左边菜单栏 <ul class="treeview-menu" id="left_menu"> <li><a href ...

  2. Android一个自定义的进度环:ProgressChart

    源代码及可执行文件下载地址:http://files.cnblogs.com/rainboy2010/ProgressChart.zip 因项目需要,自己尝试定义了一个进度环,用于显示进度,实现效果如 ...

  3. MySql两种存储引擎的区别

    MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...

  4. js学习——基础知识

    数据类型 函数.方法 变量作用域 运算符 条件语句 break和continue typeof 错误(异常) 变量提升 严格模式 JSON void(0) JavaScript            ...

  5. JS打开新的窗口

    一.使用JS打开新窗口 1. 超链接<a href="http://www.wumz.me" title="Mauger`s Blog">Welco ...

  6. js 获取当前的网址

    http://www.xcx.cc/index.php/home/index/ind?idf=12321var $cur_url=window.location.href; //获取全部的网址var ...

  7. Netty多人聊天室

    在简单聊天室的代码中修改ChatServerHandler类,就可以模拟多人聊天的功能 package com.cppdy.server; import io.netty.channel.Channe ...

  8. day 28 面向对象 三种特性之一 多态 鸭子类型 反射(反省)

    多态是OOP的三大特征之一 字面意思:多种形态 多种状态 官方描述:不同的对象可以响应(调用)同一个方法 产生不同的结果(例如水的三相特征) 多态不是什么新技术 我们编写面向对象的程序时 其实就有多态 ...

  9. 为什么访问json接口出现文件下载

    在IE9,10,11下,当服务器端返回数据格式为json,且明确设置Content-Type为”application/json;charset=utf-8“时,会提示文件下载.如图所示: 解决办法是 ...

  10. java数据

    因为曾经干了啥事儿,才印象特别深刻. 将byte存入String的后果 String res = ""; res += (char) 0xc3; byte[] bytes = re ...