Python外键

外键
外键是数据表用来指向某个外来的键值的字段
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/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值