外键和表关系
在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam。如果使用的是InnoDB引擎,是支持外键约束的。外键的存在使得ORM框架在处理表关系的时候异常的强大。因此这里我们首先来介绍下外键在Django中的使用。
类定义为class ForeignKey(to,on_delete,**options)。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有CASCADE、SET_NULL等。这里以一个实际案例来说明。比如有一个Category和一个Article两个模型。一个Category可以有多个文章,一个Article只能有一个Category,并且通过外键进行引用。
定义模型
# 分类
class Category(models.Model):
name = models.CharField(max_length=100)
# 文章
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
category = models.ForeignKey("Category", on_delete=models.CASCADE, null=True)
生成表
python manage.py makemigrations news
python manage.py migrate news
外键增加
category = Category(name="python")
category.save()
article = Article(title='Python入门', content="xxxxx")
article.category = category # 等效于 article.category_id = category
article.save()
# 有数据的情况下:Category表有数据
category = Category.objects.get(pk=1)
article = Article(title='Python入门', content="xxxxx")
article.category = category
article.save()
外键查询
# 文章的分类
article = Article.objects.get(pk=1)
print(article.category_id) # 1
category = Category.objects.get(pk=article.category_id)
print(category.name) # python
外键指向自身
模型
class Comment(models.Model):
content = models.CharField(max_length=20)
comments = models.ForeignKey("self", on_delete=models.CASCADE, null=True)
视图
# 外键引用自身 保存数据
# comment = Comment(content="hello")
# comment.save()
comment = Comment(content="ecithy")
first_comment = Comment.objects.get(pk=1)
comment.comments = first_comment
comment.save()
外键删除
如果一个模型使用了外键。那么在对那个模型被删掉后,该进行什么样的操作。可以通过on_delete来指定。可以指定的类型如下:
1.CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
2.PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。
3.SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
4.SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。
5.SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。
6.DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。