外键和表关系

在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam。如果使用的是InnoDB引擎,是支持外键约束的。外键的存在使得ORM框架在处理表关系的时候异常的强大。因此这里我们首先来介绍下外键在Django中的使用。

类定义为class ForeignKey(to,on_delete,**options)。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有CASCADE、SET_NULL等。这里以一个实际案例来说明。比如有一个Category和一个Article两个模型。一个Category可以有多个文章,一个Article只能有一个Category,并且通过外键进行引用。

定义模型

  1. # 分类
  2. class Category(models.Model):
  3. name = models.CharField(max_length=100)
  4. # 文章
  5. class Article(models.Model):
  6. title = models.CharField(max_length=200)
  7. content = models.TextField()
  8. category = models.ForeignKey("Category", on_delete=models.CASCADE, null=True)

生成表

python manage.py makemigrations news
python manage.py migrate news
image.png

外键增加

  1. category = Category(name="python")
  2. category.save()
  3. article = Article(title='Python入门', content="xxxxx")
  4. article.category = category # 等效于 article.category_id = category
  5. article.save()
  1. # 有数据的情况下:Category表有数据
  2. category = Category.objects.get(pk=1)
  3. article = Article(title='Python入门', content="xxxxx")
  4. article.category = category
  5. article.save()

image.png

外键查询

  1. # 文章的分类
  2. article = Article.objects.get(pk=1)
  3. print(article.category_id) # 1
  4. category = Category.objects.get(pk=article.category_id)
  5. print(category.name) # python

外键指向自身

模型

  1. class Comment(models.Model):
  2. content = models.CharField(max_length=20)
  3. comments = models.ForeignKey("self", on_delete=models.CASCADE, null=True)

视图

  1. # 外键引用自身 保存数据
  2. # comment = Comment(content="hello")
  3. # comment.save()
  4. comment = Comment(content="ecithy")
  5. first_comment = Comment.objects.get(pk=1)
  6. comment.comments = first_comment
  7. comment.save()

效果图
image.png

外键删除

  1. 如果一个模型使用了外键。那么在对那个模型被删掉后,该进行什么样的操作。可以通过on_delete来指定。可以指定的类型如下:
  2. 1.CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
  3. 2.PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。
  4. 3.SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
  5. 4.SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。
  6. 5.SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。
  7. 6.DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。