• Django:学习笔记(7)——模型进阶


    Django:学习笔记(7)——模型进阶

    模型的继承

      我们在面向对象的编程中,一个很重要的的版块,就是类的继承。父类保存了所有子类共有的内容,子类通过继承它来减少冗余代码并进行灵活扩展

      在Django中,父类可以是一个实际的模型(即有同步的数据表),也可以是一个抽象的模型(只用来保存子模型共有内容,并不实际创建数据表)

    抽象继承

      将一个类转换为抽象类,然后其他类再继承它,来完成抽象继承。

    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()
        class Meta:
            abstract=True
    
    class Student(CommonInfo):
        score = models.FloatField()
    

      数据迁移后,不会创建CommonInfo数据表,因为它是抽象类。

      需要说明的是,抽象基类的元数据也会被子类继承,但是abstract=True这个元数据不会被继承。子类可以继承或者重写父类的元数据

    多表继承

      这种继承方式下,父类和子类都是独立自主、功能完整、可正常使用的模型,都有自己的数据库表,内部隐含了一个一对一的关系

    from django.db import models
    
    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)
    
    class Restaurant(Place):
        serves_hot_dogs = models.BooleanField(default=False)
        serves_pizza = models.BooleanField(default=False)
    

      我们还是到数据库层面来理解所谓的一对一关系:

      

      子类ID参照了父类的ID,所以父类可以快速找到子类,子类也可以通过ID找到父亲,这是符合一对一关系的。在实际使用中,我们需要注意:

    >>> r2 = Restaurant.objects.create(serves_hot_dogs=True,serves_pizza=False, name='pizza', address='address2')
    >>> r2.place   # 可以看出这么调用都是非法的,异想天开的
    >>> p2 = Place.objects.get(name='pizza')
    >>> p2.restaurant  # 这样是可以的
    

      也就是爸爸就是爸爸,爸爸可以直接调出儿子。

      在多表继承的情况下,由于父类和子类都在数据库内有物理存在的表,父类的Meta类会对子类造成不确定的影响,因此,Django在这种情况下关闭了子类继承父类的Meta功能。但是,还有两个Meta元数据特殊一点,那就是orderingget_latest_by,这两个参数是会被继承的。因此,如果在多表继承中,你不想让你的子类继承父类的上面两种参数,就必须在子类中显示的指出或重写

     多重继承

      注意,多重继承和多表继承是两码事,两个概念。

    class Article(models.Model):
        article_id = models.AutoField(primary_key=True)
        ...
    
    class Book(models.Model):
        book_id = models.AutoField(primary_key=True)
        ...
    
    class BookReview(Book, Article):
        pass
    

      一般情况,能不要多重继承就不要,尽量让继承关系简单和直接,避免不必要的混乱和复杂。

    说明:在Python语言层面,子类可以拥有和父类相同的属性名,这样会造成覆盖现象。但是对于Django,如果继承的是一个非抽象基类,那么子类与父类之间不可以有相同的字段名。

    用包来继承模型

      在应用下创建一个model文件夹,将模型文件都放入其中,然后新建一个_init_.py导入该文件夹下的模型,来将整个文件夹作为整体模型库提供给其他地方使用。

      

      要显式明确地导入每一个模型,而不要使用from .models import *的方式,这样不会混淆命名空间,让代码更可读,更容易被分析工具使用。

  • 相关阅读:
    Hystrix解析(三)
    Hystrix解析(二)
    在阿里云开发平台编写第一个 HelloWorld 程序
    Jenkins与Docker的自动化CI/CD实战
    网页计数器例子
    ServletContext 对象
    Session
    Cookie
    Request 对象作用域
    转发,重定向(包括请求中文乱码解决)
  • 原文地址:https://www.cnblogs.com/MrSaver/p/10447539.html
Copyright © 2020-2023  润新知