目录
内嵌类Meta
通过一个内嵌类Meta来定义元数据
元数据又被称为“中介数据”,用来描述数据的数据
简单的讲Meta就是通过自定义属性描述model对象,为其提供额外功能
Meta可用的模块?
-
abstract:讲当前模型类转换成抽象类,当进行migrate的时候会被忽略
因为migrate是对实体表进行修改,而抽象是一个虚的概念,所以不存在实体。
实质性的作用:减少代码量,减少代码重复
class Person(models.Model):
name=models.CharField(max_length=64)
email = models.EmailField()
update_time=models.DateTimeField(auto_now=True)
create_time=models.DateTimeField(auto_now_add=True)
null=models.CharField(max_length=200,null=True)
blank_test=models.CharField(max_length=200, blank=True)
class Meta:
abstract=True
class Reader(Person):
wether_vip=model.BooleanField(default=False)
class Writer(Person):
pass
-
app_label:指定当前那个从属于已经注册的应用
在项目中新建一个model层,对用途进行区分,然后用此继承。但是一定要注册。
app_label = 'myapp'
如果你想用
app_label.object_name
或app_label.model_name
来表示一个模型,你可以分别使用model._meta.label
或model._meta.label_lower
。 -
db_table:Options.db_table
用于模型的数据库表的名称:db_table = music_album
-
managed
默认为True,如果为False,当前migrate会忽略该模型
class Meta:
db_table='reader'
managed=False
-
orderding
对象的默认排序,用于获取对象列表时:
ordering = ['-order_date']
这是一个字符串和/或查询表达式的元组或列表。每一个字符串都是一个字段名,前面有一个可选的“-”字头,表示降序。没有前缀“-”的字段将按升序排列。使用字符串“?”来随机排序。
例如,要按
pub_date
字段升序排列,使用以下方法:ordering = ['pub_date']
要按
pub_date
降序排列,请使用:ordering = ['-pub_date']
要按
pub_date
降序,然后按author
升序,请使用:ordering = ['-pub_date', 'author']
你也可以使用 查询表达式。要按
author
升序排列,并使空值最后排序,请使用:from django.db.models import F ordering = [F('author').asc(nulls_last=True)]
-
get_latest_by
设置获取最后一条记录的排序规则
模型中的字段名或字段名列表,通常是 DateField,DateTimeField 或 IntegerField。这指定了在你的模型中使用的默认字段 Manager 的
last()
和earliest()
方法。
# Latest by ascending order_date.
get_latest_by = "order_date"
# Latest by priority descending, order_date ascending.
get_latest_by = ['-priority', 'order_date']
- indexs
设置索引
from django.db import models
class Customer(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Meta:
indexes = [
models.Index(fields=['last_name', 'first_name']),
models.Index(fields=['first_name'], name='first_name_idx'),
]
- unique_together
多字段唯一性约束
unique_together = ['driver', 'restaurant']
模型继承
-
普通继承
class Person(models.Model):
name=models.CharField(max_length=64)
email = models.EmailField()
update_time=models.DateTimeField(auto_now=True)
create_time=models.DateTimeField(auto_now_add=True)
null=models.CharField(max_length=200,null=True)
blank_test=models.CharField(max_length=200, blank=True)
class Meta:
abstract=True
class Reader(Person):
wether_vip=model.BooleanField(default=False)
class Writer(Person):
pass
- 多重继承
from django.db import models
# Create your models here.
class Student(models.Model):
student_id=models.AutoField(primary_key=True,db_column='id')
name=models.CharField(max_length=64)
class Book(models.Model):
book_id=models.AutoField(primary_key=True,db_column='id')
book_name = models.CharField(max_length=64)
class BorownRecord(Student,Book):
_id=models.AutoField(primary_key=True, db_column='id')
borown_time=models.DateTimeField(auto_now_add=True)
在上边代码值得注意的是:
db_column='id' --->都要指定一个每个表中的id,防止起冲突
_id=models.AutoField(primary_key=True, db_column='id') 规定自己表内的id,防止因为继承的student表和book表中的id冲突矛盾
实例方法
-
获取最新记录
get_latest_by=['id'] item=model.objects.latest()
-
自定义输出
def __str__(self): return f "id:{self.id,},{self.question_text}"
-
refresh_db:刷新当前记录
-
字段唯一性验证
unique_together=["name","email"]
Django.setuP
import os
import random
import django
def create_reader():
for i in range(10):
reader = Reader(
name=f'name_{i}',
email=f'email_{i}@163.com',
null_test=None,
blank_test='',
whether_vip=random.choice([True, False])
)
# 通过clean_fields方法对当前对象进行自检
# 如果当前字段可以为None, 则需要将该字段置入exclude参数中
reader.clean_fields(exclude=['null_test'])
# 调用save会往数据插入一条数据或者更新一条数据
reader.save()
if __name__ == "__main__":
# 设置环境变量
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
django.setup()
from myblog.models import Reader
create_reader()
QuerySet
-
Create
-
save
-
-
Retrieve
Django的
orm
时一条执行链, 而不是单个语句Reader.objects.all().filter(id__gt=300).order_by("name", "id")
orm尽量使用一些简单的接口
如果查询需求比较复杂, 尽量使用SQL
-
all
获取表中所有记录
如果表非常大, 一定要小心使用.
-
get
通过指定条件, 获取一条数据, 如果有多条, 则会报错
reader = Reader.objects.get(name="name_0")
-
filter
匹配满足条件的记录, 类似于
SQL
中的WHERE
语句reader_array = Reader.objects.filter(name="name_0")
-
比较
Reader.objects.filter(id__gte=300)
-
>=
-----gte
-
>
--------gt
-
<=
-------lte
-
<
--------lt
-
-
模糊匹配
类似于
WHERE 字段 LIKE '%xx%'
-
__startswith
-
__endswith
-
__icontains
-
-
-
exlude
与
filter
逻辑取反 -
限制返回的记录数
相当于
SQL
中的limit
reader_array[:5]
-
latest
# 需要在models, Meta中指定get_latest_by Reader.objects.latest()
-
order_by
Reader.objects.all().order_by("name", "id")
-
-
Update
-
save
reader.email = "[email protected]" reader.save()
-
-
Delete
如果想对整张表进行清除, 还是truncate table命令更快
-
delete
reader.delete()
-
高级
-
RAW
遇到复杂的场景, 需要使用
SQL
语句通过Reader._meta.db_table来获取记录所在表
queryset = Reader.objects.raw(f"select * from {Reader._meta.db_table} limit 1") list(queryset)
-
指定数据库
-
在settings配置该数据库,
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'polls', 'USER': 'root', 'PASSWORD': 'qwe369', 'HOST': '127.0.0.1', 'PORT': '3306' }, 'person': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'person', 'USER': 'root', 'PASSWORD': 'qwe369', 'HOST': '127.0.0.1', 'PORT': '3306' } }
-
使用参数using
reader.save(using='person') Reader.objects.using('person').all()
-
-
事务
-
基于HTTP请求的事务
-
在
settings
中要设置ATOMIC_REQUESTS
为True
from django.db import transaction @transaction.atomic def my_view(request): 表达式...
-
-
基于视图具体逻辑的事务
from django.db import transaction def viewfunc(request): 表达式 with transaction.atomic(): 表达式A 表达式B ...
-
更多QuerySet API操作:https://docs.djangoproject.com/zh-hans/4.1/ref/models/querysets/