当前位置: 首页 > 工具软件 > Metaobjects > 使用案例 >

Django之Meta选项

佟颖逸
2023-12-01
'''
    数据库模型
    每个属性代表一个数据库的字段
'''

# CharField 相当于 varchar

'''
    Meta选项
'''
# app_label
# 用来指定你的model是属于哪个app
'''
    继承一:
'''
# 抽象基类,如果你需要将一些公共信息放在许多模型中,可以在Meta选项中设置
# abstract = True   表示作为一个基类,可以被继承,但是此类不会生成数据库,仅作为一个类
# 对Meta的继承,
# 当你在继承抽象基类的时候,如果子类没有声明Meta类,将继承父类的Meta类,也可以自己定义
'''
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'
'''


'''
    继承二:
'''
# 每个模型对应于自己的数据库表,可以单独查询和创建。继承关系引入子模型与其每个父模型之间的链接通过自动创建OneToOneField
'''
    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)
        
    >>> Place.objects.filter(name="Bob's Cafe")
    >>> Restaurant.objects.filter(name="Bob's Cafe")
    也可以通过基类查询子类
    >>> p = Place.objects.get(id=12)
    # If p is a Restaurant object, this will give the child class:
    >>> p.restaurant
'''
# 自动创建的OneToOneField
'''
    place_ptr = models.OneToOneField(
    Place, on_delete=models.CASCADE,
    parent_link=True,
)
'''
# 如果在子类中,有M2M字段,且关联父类,则需要给M2M字段添加related_name属性
'''
    class Supplier(Place):
        customers = models.ManyToManyField(Place)
'''
# 多重继承中,如果多个父类包含一个Meta类,则只会使用第一个类,而将忽略所有其他类。
# 在继承时,只能有一个主键,否则就会报错


'''
    related_name和related_query_name的用法
'''
# 在外键和多对多关系中使用,用来配置反向名称和反向查询名称,还要指定app名称和class名称
'''
    使用方法:
    
    from django.db import models
    class Base(models.Model):
        m2m = models.ManyToManyField(
            OtherModel,
            related_name="s",
            related_query_name="d",
        )

    OtherModel.objects.filter(d__name='learn java')
    other = OtherModel.objects.get(pk=1)
    other.s.all()
    
'''
# 如果指定related_name和related_query_name的话
'''
    OtherModel.objects.filter(base_set__name='learn java')
    other = OtherModel.objects.get(pk=1)
    other.Base_set.all()
'''

# 代理模型,设置proxy=True来告诉django这是一个代理(继承的必须是非抽象类且只能代理一个数据库表单)
'''
    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
    
    class MyPerson(Person):
        class Meta:
            proxy = True
    
        def do_something(self):
            # ...
            pass
            
    >>> p = Person.objects.create(first_name="foobar")
    >>> MyPerson.objects.get(first_name="foobar")
    
    可以进行各种操作
'''

'''
# indexes = (fields =(),name = None,db_tablespace = None, opclasses =(),condition = None)  索引配置
'''
'''
    db_tablespace   用于索引的数据库表空间
	opclasses  用于此索引的PostgreSQL运算符类的名称。使用时需要定义Index.name
	GinIndex(name='json_index', fields=['jsonfield'], opclasses=['jsonb_path_ops']
	condition   索引限制
	condition=Q(pages__gt=400) 索引记录超过400的。

'''
# index_together=[]   组合索引
# unique_together=[]   联合主键
# base_manager_name 用于设置模型的管理器_base_manager的名称
# default_manager_name  用于设置模型的管理器_default_manager的名称
# default_related_name  与字段中的related_query_name类似

'''
    class Foo(models.Model):
        pass
    class Bar(models.Model):
        foo = models.ForeignKey(Foo)
    
        class Meta:
            default_related_name = 'bars'   
    >>> bar = Bar.objects.get(pk=1)
    >>> # 不能再使用"bar"作为反向查询的关键字了。
    >>> Foo.objects.get(bar=bar)
    >>> # 而要使用你自己定义的"bars"了。
    >>> Foo.objects.get(bars=bar)
'''
# db_table 用来设置模型的数据库表单的名称
# get_latest_by 为了使用模型中的 latest()和 earliest()方法,要配置这个选项
# get_latest_by = ["",""]  列表中的元素为字段名,与ordering里面的字段用法类似
# managed 默认为True,Django会管理该数据库表的生命周期,为False则不会对此模型执行数据库表创建或删除操作

'''
    order_with_respect_to
    通常用在ForeignKey中
    当order_with_respect_to设置,提供了两个额外的方法来检索和设置相关对象的顺序:get_RELATED_order() 和set_RELATED_order(),
    其中RELATED是小写的表名称。例如,假设一个Question对象有多个相关Answer对象,
    
'''
# 示例:
'''
    class Question(models.Model):
        text = models.TextField()
        # ...
    
    class Answer(models.Model):
        question = models.ForeignKey(Question, on_delete=models.CASCADE)
        # ...
    
        class Meta:
            order_with_respect_to = 'question'
    
    在创建数据库表的时候,Answer表中会自动新建一个_order字段,该字段用来存储排序的序号,按外键进行分类(从0开始)
'''
# 使用方法:
'''
    >>> question = Question.objects.get(id=1)
    >>> question.get_answer_order()   默认是按照创建的顺序排列
    <QuerySet [1, 2, 3, 4]>

    question.set_answer_order([3, 1, 2, 4])  也可以自定义排序,这会改变_order字段的值
    _order字段的值按照顺序会变为[1,2,0,3]
    
    改变顺序后,执行下面操作
    >>> answer = Answer.objects.get(id=2)
    >>> answer.get_next_in_order()   获取下一行数据
    <Answer: Answer object (4)>
    >>> answer.get_previous_in_order()  获取前一行数据
    <Answer: Answer object (1)>
    
'''
# ordering 设置对象的默认顺序
'''
    ordering = ['pub_date']  升序
    ordering = ['-pub_date']  降序
    也可以使用查询表达式,author升序排序,并将空值排在最后
    ordering = [F('author').asc(nulls_last=True)]
'''

# permissions 创建此对象时进入权限表的额外权限。为每个模型自动创建添加,更改,删除和查看权限
# permissions = [('can_deliver_pizzas', 'Can deliver pizzas')]

# default_permissions  Django默认给所有的模型设置('add', 'change', 'delete', 'view').
# 你可以自定义这个选项,比如设置为一个空列表,表示你不需要默认的权限,但是这一操作必须在执行migrate命令之前。

# required_db_features 如果将此列表设置为['gis_enabled'],则仅在启用GIS的数据库上同步模型

# required_db_vendor 声明模型支持的数据库。Django默认支持sqlite, postgresql, mysql, oracle,如果此属性不为空且当前连接供应商与其不匹配,则不会同步模型。

# select_on_save,默认值是False,决定是否使用1.6版本之前的django.db.models.Model.save()算法保存对象

# constraints 要在模型上定义的约束列表
'''
    constraints = [
                models.CheckConstraint(check=models.Q(age__gte=18), name='age_gte_18'),
            ]
    年龄小于等于18
'''

# verbose_name 用来设置数据库表的名称,最常用的配置(单数名,就是英语中的单复数)
# verbose_name = "博客"

# verbose_name_plural 数据库表的复数名称,如果不设置则为 verbose_name + 's'

# label  只读元数据,等同于app_label.object_name
# label_lower 与上面相同,只不过是小写的模型名称

# 暂定, Manager()没有学的很清楚

'''
    from django.db import models
    
    class Person(models.Model):
        # Add manager with another name
        people = models.Manager()
'''
# 每个非抽象Model类至少有一个Manager,也可以自定义,(查询方法)
 类似资料: