Django-外键

什么是外键?

外键是数据表用来指向某个外来的键值的字段。

为什么使用外键?

1.取出冗余数据

2.数据结构化,使用和执行效率变高

3.便于管理,更好存储数据。

外键的种类

常见外键:ForeignKey

多对多:ManyToManyField

一对一:OneToOneField

万能外键:ContentType

ForeignKey

```python

from django.dbimport models

#coding=utf-8

# Create your models here.

class StudentClass(models.Model):

    name= models.CharField(max_length=12,help_text='班级名称')

master= models.CharField(max_length=12,help_text='班主任')

def __str__(self):

        return 'StudentClass:' + self.name

class Student(models.Model):

    name= models.CharField(max_length=12,help_text='学生姓名')

school_class= models.ForeignKey(StudentClass,on_delete=models.CASCADE)

#(on_delete 属性说明)

    #django 1.9一定需要的

    #1.CASCADE,级联删除

    #当班级记录删除时,删除对应的所有学会

    #2.DO_NOTHING 什么都不做

    #会破坏数据的完整性

    #3.PROTECT 保护

    #当班级删除记录的时候,若有学生关联班级,则不给删除班级

    #4.SET_NULL,设置为NULL

    #当班级删除记录的时候,若有学生关联该班级,则这些学生的班级关联字段全都设置为NULL

# school_class = models.ForeignKey(StudentClass,on_delete=models.SET_NULL, null=True)

    #5.SET_DEFAULT 设置为默认值

    # def default_class():

#    return SchoolClass.objects.first()

# school_class = models.ForeignKey(StudentClass, on_delete=models.SET_DEFAULT, default=default_class)

    #6.SET() 自定义方法,返回一个值,设置该字段的值

    """

    外键查询数据    1.正向查询s = student.objects.first()

    s.school_class #找到关联的班级对象"""

"""

    2.反向查询c = StudentCLass.objects.first()

c.student_set.all()

    related_name, 明确关系,班级通过什么属性找到学生school_class = models.ForeignKey(StudentClass, on_delete=moels.CASCADE, related_name='student')

c = StudentClass.objects.first()

c.student.all()

    """

```

MangToManyField

如:一本书可能有多个作者,一个作者可能出了多本书

```

#coding=utf-8

from django.dbimport models

# Create your models here.

class Author(models.Model):

    author_name= models.CharField(max_length=50)

def __str__(self):

        return 'author_name:'+ self.author_name

class Book(models.Model):

    book_name= models.CharField(max_length=50)

authors= models.ManyToManyField(Author,through='BookAuthor')

class BookAuthor(models.Model):

    author= models.ForeignKey(Author,on_delete=models.CASCADE)

book= models.ForeignKey(Book,on_delete=models.CASCADE)

#还可以添加额外字段

#dir()找到它有那些属性

#多对多字段会创建一个维护多对多关系的表 默认book_author表

#可以使用through 指向中间表,自己来创建这个中间表

"""

正向查询book = Book.objects.first()

authors = book.author.all()

反向查询author = Author.objects.first()

books = author.book_set.all()  #如果指定了relate_name 那么就要换名称了related_name,明确关系,同ForeignKey

authors = models.ManyToManyField(Author, related_name = 'books')

编辑ManyToMany 字段,无需执行save()保存add,remove,clear

book = Book.objects.first()

author = author.objects.first()

1.书增加新作者book.authors.add(author)

2.书移除作者book.authors.remove(author)

3.作者添加书籍author.book_set.add(book)

4.作者删除书籍author.boos_set.remove(book)

"""

```

OneToOneField

如:Django用户表和自定义用户拓展表

```

on_delete

class Profile(models.Model):

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

    nickname = models.CharField(max_length=24)

'''

正向

profile = Profile.objects.first()

user = profile.user

反向

user = User.objects.first()

profile = user.profile

编辑该字段直接赋值就可以

'''

```

ContentType

如:评论任何对象,评论表不仅能指向文章,还可以指向视频

1.评论表中有两个字段维护这个关系

一个记录类型

一个记录值

class Viedo(models.Model): ...

class Article(models.Model): ...

class Comment(models.Model):

    content_type = models.ForeignKey(ContentType, on_delete = CASCADE) #记录关联对象的类型

    object_id = models.PositiveIntegerField() #记录关联对象的主键值

    content_objects  = GenericForeignKey('content_type' , 'object_id)#常规字段,便于使用

    text=...#评论内容

'''

正向:

comment = Comment.objects.first()

obj = comment.content_object #直接得到被评论的对象

反向:无法直接从其他对象找到Comment对应的评论

from django.contrib.contenttypes.models import ContentType

article = Article.objects.first()

article_content_type = ContentType.objects.get_for_model(article)


#通过Comment自身的筛选车寻得到

comments = Comment.objects.filter(content_type =rticle_content_type, object_id = article.pk)


反向方法2:主动建立关系

from django.contrib.contenttypes.fields import GenericRelation

#对应模型加入 comments = GenericRelation(‘Comment')字段

article = Article.objects.first()
comments = article.comments.all()

'''

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容