一、数据库表关系
单表
重复的字段太多,所以需要一对多,多对多来简化

多表 多对一 多对多 一对一 =============================================== 一对多: Book id title price publish_id 1 php 100 1 2 python 200 1 3 go 300 2 Publish id name email addr 1 人名出版社 @ 北京 2 沙河出版社 @ 沙河 一旦确定是 一对多 怎么建立一对多的关系?---》 关联字段 ,建在‘多’的表中 查询python这本书的出版社的邮箱 (子查询) select email from Publish where id = ( select publish_id from Book where title = 'python' ) =============================================== 多对多:(彼此一对多) Book id title price publish_id 1 php 100 1 2 python 200 1 3 go 300 2 Author id name age addr 1 alex 34 beijing 2 egon 29 nanjing
Book2Author id book_id author_id 1 2 1 2 2 2 3 3 2 alex 出版过的书籍名称 (子查询:以一个查询的结果作为下一个查询的条件) select title from Book where id in ( select book_id from Book2Author where author_id = ( select id from Author where name = 'alex' ) ) =============================================== 一对一: Author id name age authordetail_id(unique) (一定要加) 1 alex 34 1 2 egon 29 2 AuthorDetail (这个信息不经常查,为了效率,扩展) id addr gender tel gf_name 1 beijing male 110 小花 2 nanjing male 911 红花 =============================================== 总结: 一旦确定是 一对多 怎么建立一对多的关系?---》 关联字段 ,建在‘多’的表中 一旦确定是 多对多 怎么建立多对多的关系?---》 创建第三张表(关联表): id 和 两个关联字段 一旦确定是 一对一 怎么建立一对一的关系?---》 在两张表中的任意一张表中建立关联字段 + unique
Publish Book AuthorDetail Author Book2Author ===================================================== create table publish( id int primary key auto_increment, name varchar(20) ); create table book( id int primary key auto_increment, title varchar(20), price decimal(8,2), pub_date date, publish_id int, foreign key (publish_id) references publish(id) ); create table authordetail( id int primary key auto_increment, tel varchar(20) ); create table author( id int primary key auto_increment, name varchar(20), age int, authordetail_id int unique, foreign key (authordetail_id) references authordetail(id) ); create table book2author( id int primary key auto_increment, book_id int, author_id int ); =====================================================
pycharm自带 database配置--sqlite3
orm参数
https://www.cnblogs.com/liwenzhou/p/8688919.html
二、ORM生成关联表模型
'' Book Publish Author AuthorDetail Book2Author 会自定生成 Book -- Publish 一对多 Author -- AuthorDetail 一对一 Book -- Author 多对多 Book2Author ''' from django.db import models # 作者详情表 class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday = models.DateField() telephone = models.BigIntegerField() addr = models.CharField(max_length=64) class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() # 一对一 关系 这里会生成一个字段 authordetail_id authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE) class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() # def __str__(self): # 打印的时候 可以打印出name # return self.name class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=8,decimal_places=2) # 一对多 关系 # 这里会生成一个 字段 publish_id publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) ''' publish_id int, foreign key (publish_id) references publish(id) ''' # 多对多 # 这里会生成第三张表 book_authors authors = models.ManyToManyField(to='Author') ''' create table book_authors( id int primary key auto_increment, book_id int, author_id int ); ''' def __str__(self): return self.title # 这里生成第三张表的本质 # django 去写不用我们写 # class Book2Author(models.Model): # nid = models.AutoField(primary_key=True) # book = models.ForeignKey(to='Book') # 默认关联主键 # author = models.ForeignKey(to='Author') ''' 数据库迁移 python manage.py makemigrations python manage.py migrate ''' ''' 注: # 这就是django2.0问题 authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid') TypeError: __init__() missing 1 required positional argument: 'on_delete' 解决办法: authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) 需要加上 on_delete = models.CASCADE django1 默认加上了 on_delete '''
多对多创建方法:
# 级联删除字段必须加否则创建时报错 on_delete=models.CASCADE 一对多 一对一 publish = models.ForeignKey(to=Publish, to_field='nid', on_delete=models.CASCADE) authordeatil = models.OneToOneField(to="AuthorDetail", to_field="nid", on_delete=models.CASCADE) # authors = models.ManyToManyField(to="Author") 多对多 不会报错
利用pycharm自带的sqlite数据库
python manage.py makemigrations
python manage.py migrate
生成数据库表:
注意事项:
- 表的名称
myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称 -
id字段是自动添加的 - 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
- 这个例子中的
CREATE TABLESQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。 - 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py所在应用的名称。 - 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
多表操作 添加记录
1.单表
from app01.models import * def add(request): pub=Publish.objects.create(name='人民出版社',email='123@qq.com',city='武汉') return HttpResponse('OK')
表的创建关系
================一对多====================
方式一:
# 为book表绑定关系 book---------publish book_obj=Book.objects.create(title='红楼梦',price=100,publishDate='2012-1-1',publish_id=1) print(book_obj.title)
方式二:
# 方式2 # publish_obj = Publish.objects.filter(id=2).first() # 没有id属性 publish_obj = Publish.objects.filter(nid=2).first() # 先查找publish_obj 对象 book_obj = Book.objects.create( title='红楼梦', price=200, publishDate="2012-11-11", publish=publish_obj,#出版社对象 ) print(book_obj.title) print(book_obj.price) print(book_obj.publishDate) print(book_obj.publish) # 与这本书关联的出版社对象 print(book_obj.publish.email) # 出版社对象,可以继续 使用 点方法 print(book_obj.publish_id)
每张表加
查询 出版 三国演义 出版社的邮箱
=============================绑定多对多的关系==================================
from django.shortcuts import render,HttpResponse from app01.models import * def add(request): # 单表 pub = Publish.objects.create(name='人名出版社',city='陕西',email='1234@qq.com') # =============================绑定一对多的关系================================== # 方式一 book -- publish book_obj = Book.objects.create(title='西游记',publishDate='2012-12-1',price=100,publish_id=1) print(book_obj.title) # 西游记 print(book_obj.publish) # Publish object (1) print(book_obj.publish_id) # 1 # 方式二 pub_obj = Publish.objects.filter(nid = 2).first() # 对象 book_obj = Book.objects.create(title='放风筝得人',publishDate='2012-1-2',price=150,publish=pub_obj) print(book_obj.title) # 放风筝得人 print(book_obj.price) # 150 print(book_obj.publish_id) # 3 print(book_obj.publish) # Publish object (3) print(book_obj.publish.name) # 人名出版社 print(book_obj.publish.city) # 陕西 # 查询西游记这本书,出版社对应的邮箱 book_obj = Book.objects.filter(title='西游记').first() print(book_obj.publish.email) # yuan@163.com # =============================绑定多对多的关系================================== book_obj = Book.objects.create(title='西游记',publishDate='2009-11-20',price=100,publish_id=3) egon = Author.objects.get(name='egon') alex = Author.objects.get(name='alex') # Book_author django 自己加的 你没办法操作 加数据 # django 找到第三张表 添加数据 绑定多对多关系的API book_obj.authors.add(egon,alex) book_obj.authors.add(1,2) book_obj.authors.add(*[1,2]) # # 等效于 传位置参数时 加 * # 解除 多对多的 关系 book_obj = Book.objects.filter(nid=4).first() book_obj.authors.remove(2) book_obj.authors.remove(1,2) book_obj.authors.remove(*[1,2]) # 全解除 book_obj.authors.clear() # 查询出所有作者对象集合 print(book_obj.authors.all()) # #queryset [obj1.obj2] # 与这本书关联的所有作者对象 # 查询主键为4 的书籍的 所有作者的名字 print(book_obj.authors.all().values('name')) # # <QuerySet [{'name': 'alex'}, {'name': 'egon'}]>