'''
数据库模型
每个属性代表一个数据库的字段
'''
# 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,也可以自定义,(查询方法)