Python外键

    技术2022-07-16  89

    外键

    外键是数据表用来指向某个外来的键值的字段
    1.外键的作用:
    1.去除冗余的数据 2.数据结构化,使用和执行效率更高 3.便于管理,更好地存储数据. 总结:重复的数据,不同类型的内容
    2.ForeignKey
    from django.db import models # 班级表 class SchoolClass(models.Model): class_name = models.CharField(max_length=32) class_master = models.CharField(max_length=32) def __str__(self): return self.class_name class Student(models.Model): name = models.CharField(max_length=32) SEX_CHOICE = { (0, "男"), (1, "女") } sex = models.IntegerField(choices=SEX_CHOICE, default=0) student_class = models.ForeignKey(to="SchoolClass", on_delete=models.CASCADE) # on_delete 属性说明:必填,对应关联的记录(班级),删除的时候,该记录(学生)怎么处理 # 1. models.CASCADE 级联删除 # 当班级记录删除时,删除所有的学生信息,确保数据完整 # 2. models.PROTECT 保护 # 当班级记录删除的时候,若有学生关联班级,则不给删除班级 # 3. models.SET_NULL 设置为NULL # 当班级记录删除的时候,若有学生关联班级,则将这些学生的班级外键字段,值设置为NULL # student_class = models.ForeignKey(to="SchoolClass", on_delete=models.CASCADE, null=True) # 4. models.SET_DEFAULT 设置默认值 # def default_class(self): # return SchoolClass.objects.first() # student_class = models.ForeignKey(to="SchoolClass", on_delete=models.SET_DEFAULT, default=default_class) # 需要设置默认值 # 5. models.SET() # 自定义方法, 返回一个值,设置该字段的值 # 6. models.DO_NOTHING 什么也不做 # 这个会破坏数据的完整性, 慎用 # (正向:顺理成章) # s = Student.objects.first() # s.school_class # 找到关联的班级对象 # (反向:冥冥之中) # c = SchoolClass.objects.first() # c.student_set.all() # xxxx_set 找到被关联的对象 # related_name,明确关系,班级通过什么属性找到学生 # school_class = models.ForeignKey(SchoolClass, on_delete=models.CASCADE, related_name='students') # c = SchoolClass.objects.first() # c.students.all() # 编辑该字段,直接赋值即可 # c = SchoolClass.objects.first() # s = Student() # s.student_name = 'test' # s.school_class = c # s.save() def __str__(self): return self.name
    3.ManyToMantField
    from django.db import models # Create your models here. # 作者表 class Author(models.Model): author_name = models.CharField(max_length=24) def __str__(self): return '<Author: {0}>'.format(self.author_name) __unicode__ = __str__ # 书籍表 class Book(models.Model): book_name = models.CharField(max_length=48) authors = models.ManyToManyField(Author) def __str__(self): return '<Book: {0}>'.format(self.book_name) __unicode__ = __str__ # 正向(顺理成章) # book = Book.objects.first() # authors = book.authors.all() # 获得该书所有作者 # 反向(冥冥之中) # author = Author.objects.first() # books = author.book_set.all() # 获得该作者所有书 # related_name,明确关系,同ForeignKey # authors = models.ManyToManyField(Author, related_name='books') # 编辑ManyToMany字段,无需执行save()保存 # 参考:https://docs.djangoproject.com/en/2.2/ref/models/relations/#django.db.models.fields.related.RelatedManager # 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.book_set.remove(book)
    4.OneToOneField
    from django.db import models from django.contrib.auth.models import User # Create your models here. class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) nickname = models.CharField(max_length=24) def __str__(self): return '<Profile: {0}>'.format(self.nickname) __unicode__ = __str__ # 基本使用方法和ForeignKey一样 # 正向:顺理成章 # profile = Profile.objects.first() # user = profile.user # 反向:冥冥之中,我知道你的存在 # user = User.objects.first() # profile = user.profile # 编辑该字段,直接赋值即可
    5.ContentType
    from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType # Create your models here. # 文章表 class Article(models.Model): title = models.CharField(max_length=36) content = models.TextField(blank=True) # comments = GenericRelation('Comment') # 由于Comment后面才定义,所以用字符串惰性引用 def __str__(self): return '<Article: {0}>'.format(self.title) __unicode__ = __str__ # 视频表 class Video(models.Model): video_name = models.CharField(max_length=36) url = models.URLField() def __str__(self): return '<Video: {0}>'.format(self.video_name) __unicode__ = __str__ # 评论表 class Comment(models.Model): # 无法同时指向多个对象 # article = models.ForeignKey(Article, on_delete=models.CASCADE) # video = models.ForeignKey(Video, on_delete=models.CASCADE) # 万能关系 content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) # 记录关联对象的类型 object_id = models.PositiveIntegerField() # 记录关联对象的主键值 content_object = GenericForeignKey('content_type', 'object_id') # 常规字段,便于使用 # 评论内容 text = models.TextField() def __str__(self): return '<Comment: {0}>'.format(self.text) __unicode__ = __str__ # 正向,使用content_object可直接访问 ''' 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=article_content_type, object_id=article.pk) ''' # 反向,方法2,主动建立关系 # 参考:https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/#reverse-generic-relations ''' from django.contrib.contenttypes.fields import GenericRelation # 对应模型加入 comments = GenericRelation('Comment') 字段 article = Article.objects.first() comments = article.comments.all() ''' # content type 官方文档 # https://docs.djangoproject.com/en/2.2/ref/contrib/contenttypes/
    Processed: 0.011, SQL: 9