foreign key options mysql外键_Django 外键和表关系

外键

mysql中常见2种引擎,一种是InnoDB,另外一个是MyIsam。InnoDB引擎是支持外键约束的,外键的存在使得ORM框架在处理表关系的时候异常的强大。类定义为class Foreignkey(to,on_delete,**options)第一个参数是引用的哪个模型

第二个参数是在使用外键引用的模型数据被删除了,这个字段如何处理。比如有CASCADE(默认的选项,级联删除)、SET_NULL(置空模式,删除的时候,外键字段被设置为空)等。1

2

3

4

5

6

7

8

9

10

11

12# models.py

# User模型在user这个app中

calss User(models.Model):

username = models.CharField(max_length=20)

password = models.CahrField(max_length=200)

# Article模型在article这个app中

class Article(model.Molde):

title = models.CharField(max_length=100)

content = models.TextField()

author = models.ForeignKey("user.User",on_delete=models.CASCADE)

# category = models.ForeignKey("User",on_delete=models.CASCADE,null=True)

# 如果外键是在其他app上,写法是:app.模型名

如果模型的外键引用的是本身自己这个模型,那么to参数可以为self,或者是这个模型的名字。在论坛开发中,定义模型就需要使用外键来引用自身。1

2

3

4

5class Comment(models.Model):

content = models.TextField()

origin_comment = models.ForeignKey('self',on_delete=models.CASCADE,null=True)

# 或者

# models.ForeignKey('Comment',on_delete=models.CASCADE,null=True)

外键删除操作

如果一个模型使用了外键,那么在对方那个模型被删除后,该进行什么样的操作。可以通过on_delete来指定,可以指定的类型如下:1

2

3

4

5

6

7

8

9

10

11

12

13# urls.py

from django.urls import path

from book import views

urlpatterns = [

# path('',views.index),

path('delete/',views.delete_view)

]

# views.py

def delete_view(request):

category = Category.objects.get(pk=1)

category.delete()

return HttpResponse("delete success!")CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。

PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。

SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。

SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。

SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。

DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。

表关系

表之间的关系都是通过外键来进行关联的,包括三种关系:一对一、一对多(多对一)、多对多等。一对多应用场景:比如文章和作者之间的关系,一个文章只能由一个作者编写,但是一个作者可以写多篇文章。这种就是典型的一对多关系。

实现方式:一对多或者多对一,都是通过ForeignKey来实现的。1

2

3

4

5

6

7class User(models.Model):

username = models.CharField(max_length=20)

password = models.CharField(max_length=100)

class Article(models.Model):

title = models.CahrField(max_length=100)

content = models.TextField()

author = models.ForeignKey("User",on_delete=models.CASCADE)

那么以后在给Article对象指定author就可以使用以下代码来完成1

2

3

4

5

6article = Article(title='abc',content='123')

author = User(username='hahawa',password='123.com')

# 要先保存到数据库中

author.save()

article.author = author

article.save()1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18def one_to_many_view(request):

# 1.一对多

# article = Article(title='钢铁是怎样炼成的',content='just do it')

# category = Category.objects.first()

# author = frontUser.objects.first()

# article.category = category

# article.author= author

# article.save()

# 2.获取某个分类下所有稳赚

# category = Category.objects.first()

# articles = category.article_set.all()

# for i in articles:

# print(i)

# 3.添加数据,bulk

category = Category.objects.first()

article = Article(title='111',content='222')

article.author = frontUser.objects.first()

category.article_set.add(article,bulk=False)一对一应用场景:比如一个用户表和一个用户信息表。如果把所有信息都存放到一张表中可能会影响查询效率,因此可以把用户的一些不常用的信息存放到另外一张表中我们叫做UserExtension。但是用户表User和用户信息表UserExtension就是典型的一对一了。

实现方式:Django为一对一提供了一个专门的Field叫做OneToOneField来实现一对一操作。1

2

3

4

5

6

7class User(models.Model):

username = models.CharField(max_length=20)

password = models.CharField(max_length=100)

class UserExtension(models.Model):

birthday = models.DateTimeField(null=True)

school = models.CharField(blank=True,max_length=50)

user = models.OneToOneField("User", on_delete=models.CASCADE)

在UserExtension模型上增加了一个一对一的关系映射。其实底层是在UserExtension这个表上增加了一个user_id,来和user表进行关联,并且这个外键数据在表中必须是唯一的,来保证一对一。多对多应用场景:比如文章和标签的关系。一篇文章可以有多个标签,一个标签可以被多个文章所引用。因此标签和文章的关系是典型的多对多的关系。

实现方式:Django为这种多对多的实现提供了专门的Field。叫做ManyToManyField。1

2

3

4

5

6class Article(models.Model):

title = models.CharField(max_length=100)

content = models.TextField()

tags = models.ManyToManyField("Tag",related_name="articles")

class Tag(models.Model):

name = models.CharField(max_length=50)

在数据库层面,实际上Django是为这种多对多的关系建立了一个中间表。这个中间表分别定义了两个外键,引用到article和tag两张表的主键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值