目录
Django Meta中proxy、abstract、managed使用方法
proxy
使用 多表继承 时,每个子类模型都会创建一张新表。这一般是期望的行为,因为子类需要一个地方存储基类中不存在的额外数据字段。不过,有时候你只想修改模型的 Python 级行为——可能是修改默认管理器,或添加一个方法。
这是代理模型继承的目的:为原模型创建一个 代理。你可以创建,删除和更新代理模型的实例,所以的数据都会存储的像你使用原模型(未代理的)一样。不同点是你可以修改代理默认的模型排序和默认管理器,而不需要修改原模型。
代理模型就像普通模型一样申明。你需要告诉 Django 这是一个代理模型,通过将 Meta
类的proxy
属性设置为 True
。
例如,假设你想为 Person
模型添加一个方法。你可以这么做:
from django.db import models
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
MyPerson
类与父类 Person
操作同一张数据表。特别提醒, Person
的实例能通过 MyPerson
访问,反之亦然。
>>> p = Person.objects.create(first_name="foobar")
>>> MyPerson.objects.get(first_name="foobar")
<MyPerson: foobar>
你也可以用代理模型定义模型的另一种不同的默认排序方法。你也许不期望总对 “Persion” 进行排序,但是在使用代理时,总是依据 “last_name” 属性进行排序:
class OrderedPerson(Person):
class Meta:
ordering = ["last_name"]
proxy = True
现在,普通的 Person
查询结果不会被排序,但 OrderdPerson
查询接轨会按 last_name
排序。
代理模型继承“Meta”属性和普通模型一样。
QuerySet 仍会返回请求的模型
当你用 Person
对象查询时,Django 永远不会返回 MyPerson
对象。Person
对象的查询结果集总是返回对应类型。代理对象存在的全部意义是帮你复用原 Person
提供的代码和自定义的功能代码(并未依赖其它代码)。不存在什么方法能在你创建完代理后,帮你替换所有 Person
(或其它)模型。
abstract
"abstract" 参数在 Django 的 Meta 中用于标识一个模型是否为抽象模型。多用于存放公共的字段然后被继承。
当一个模型被定义为抽象模型时,它不会创建一张数据库表,并且仅仅作为一个基类被其他模型继承。抽象模型可以定义共同的字段和方法,这样可以在子类中重用。
格式如下:
class AbstractBase(models.Model):
common_field = models.CharField(max_length=100)
class Meta:
abstract = True
class SubclassA(AbstractBase):
another_field = models.CharField(max_length=100)
class SubclassB(AbstractBase):
another_field = models.CharField(max_length=100)
在这个例子中,AbstractBase
是一个抽象模型,它具有一个共同的字段 common_field
。SubclassA
和 SubclassB
都是 AbstractBase
的子类,它们继承了 common_field
字段,并且可以定义自己的字段,如 another_field
。
managed
在models里再写模型是为了能用django orm操作改表
class BookPublish(models.Model): # 这是个view
detail = models.CharField(max_length=100) # 在这里加字段没有任何作用,因为是视图
class Meta:
managed = False
db_table = 'book_publish'
"managed" 参数在 Django 的 Meta 中用于控制是否让 Django 管理模型的数据库表的生成和迁移。
默认情况下,如果不指定 "managed" 参数,Django 会自动管理模型的数据库表。也就是说,Django 会在每次数据库迁移时,根据模型的字段和参数,更新数据库表的结构。
如果设置 "managed" 参数为 False
,则不会由 Django 自动管理该模型的数据库表,并且不会在数据库迁移时更新表结构。这通常用于与外部数据库或应用程序进行集成,并且想要避免 Django 对数据库表进行任何更改。
格式如下:
class ExternalTable(models.Model):
external_field = models.CharField(max_length=100)
class Meta:
managed = False
在这个例子中,ExternalTable
是一个不由 Django 管理的模型,它具有一个名为 external_field
的字段。由于 "managed" 参数设置为 False
,因此 Django 不会在数据库迁移时更新该模型的数据库表。