外键种类
ForeignKey 一对多
ManyToManyFielf 多对多
OneToOneField 一对一
参数
to 引用的模型类(自关联“self”)
on_delete 外键约束:
model.CASCADE 级联操作(多对一,一的一方删除,多的一方也删除)
model.PROTECT 报异常(被引用的一方不能删除)
model.SET_NULL 设置为null(多对一,一的一方删除,多的一方外键为Null)
model.DO_NOTHING 什么也不做
related_name 反向引用,如果两个表间有多种外键关系,需要之模related_name,如果指明,默认是【模型类小写】_set
例子
1 首先创建模型类,用户和帖子:
class User2(models.Model):
username= models.CharField(max_length=16)
class News(models.Model):
topic = models.CharField(max_length=100)
sender = models.ForeignKey(to=User2,on_delete=models.CASCADE)
2 生成迁移文件,数据库会出现两张表:
python manage.py makemigrations
python manage.py migrate
3 进入交互环境:python manage.py shell
首先先导入所有:from user.models import *
实例化一个对象:user = User2()
user.username=‘name1’
user.save()
实例化一个帖子:news= News()
news.topic='topic1'
news.sender = user
news.save()
查看: news.sender
返回的是:<User2: User2 object (1)>
news.sender.username
'name1'
user # 查看用户
<User2: User2 object (1)>
user.news_set
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_
manager..RelatedManager at 0x27b4e9c0948>
user.news_set.all() # 查看用户所发的所有帖子
<QuerySet [<News: News object (1)>]>
user.news_set.all()[0] # 查看第一个帖子
<News: News object (1)>
user.news_set.all()[0].topic 查看topic
'topic1'
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
多对多
1)在News的模型中修改成:
class News(models.Model):
topic = models.CharField(max_length=100)
sender = models.ForeignKey(to=User2,on_delete=models.CASCADE,related_name='sender_set')
collectors = models.ManyToManyField(to=User2,related_name='collectors_set')
重新生成迁移文件并执行迁移文件!
再进入交互环境!
- 仍是先导入所有:from user.models import *
- 得到对象: news = News.objects.get(id=1)
user = User2.objects.get(id=1) - 设置user1收藏topic: user.collectors_set.add(news)
user.save() - 用户收藏了几个帖子: user.collectors_set.all()
<QuerySet [<News: News object (1)>]> - 帖子: news
<News: News object (1)>
news.collectors
<django.db.models.fields.related_descriptors.create_forward_many_to_many_
manager..ManyRelatedManager at 0x1fc004ff308> - 帖子被几个用户收藏: news.collectors.all()
<QuerySet [<User2: User2 object (1)>]> - 新增一个用户:user2 = User2()
user2.username = ‘name2’
user2.save() - 设置收藏者为第二个:news.collectors.add(user2)
news.save() - 打印topic: news.topic
‘topic1’ - 查看收藏topic1的有几个用户: news.collectors.all()
<QuerySet [<User2: User2 object (1)>, <User2: User2 object (2)>]> - 因为定义的问题,用户发送帖子只能用set来查看:
user.sender_set.all()
<QuerySet [<News: News object (1)>]>
上下次级
在models中建立一个对象:
class Area(models.Model):
name = models.CharField(max_length=10)
pArea = models.ForeignKey(to='self',null=True,on_delete=models.CASCADE)
生成迁移文件并执行,进入交互环境:
In [1]: from user.models import Area
In [2]: area=Area()
In [3]: area.name='beijing'
In [4]: area.save()
In [5]: area2 = Area()
In [6]: area2.name = 'chaoyang'
In [7]: area2.pArea= area
In [8]: area2.save()
In [9]: area.area_set.all()
Out[9]: <QuerySet [<Area: Area object (2)>]>
In [10]: area.area_set.all()[0].name
Out[10]: 'chaoyang'
In [11]: area2
Out[11]: <Area: Area object (2)>
In [12]: area2.name
Out[12]: 'chaoyang'
In [13]: area2.pArea
Out[13]: <Area: Area object (1)>