Django-模型

Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
from django.db import models

# 字段选项
class Person(models.Model):
Choices = (
('1', 'a'),
('2', 'b'),
)
name = models.CharField(max_length=30, null=True, blank=True, choices=Choices,
default='wcg', help_text='', primary_key=True, unique=True,
db_colum='', #数据库列名称
db_index=True,
db_tablespace='', #已编入索引数据库表空间的名称
editable=True, #默认是True,如False,不会显示
error_message='',
unique_for_data/month/year,
verbose_name='', #人类可读名称
validators=[]) #验证
id = models.AutoField(primary_key=True)

# 字段类型
AutoField/BigAutoField/BigInterField/BinaryField
CharField(max_length=10)
BooleanField(default=True)
DataField(auto_now=True, auto_now_add=True) #仅在save是更新,创建对象,更新到现在
DataTimeField(auto_now=True, auto_now_add=True)
TimeField(auto_now=True, auto_now_add=True)
DecimalField(..., max_digits=5, decimal_places=2) #固定精度的十进制数
DurationField() #存储时间段的字段
EmailField(max_lenght=50)
FileField(upload_to='uploads/%Y/%m/%d/', max_length=100) #FieldFile
FilePathField(path='/home/images', match='foo.*', recursive=True)
FloatField()
ImageField(upload_to='', height_field=None, width_field=None, max_length=100)
IntegerField()
PositiveIntegerField() #正数或零
GenericIPAddressField(protocol='both/IPv4/IPv6', unpack_ipv4=True)
SlugField(max_length=50) #标签,只包含字母,数字,下划线或连字符,通常用于url
TextField()
URLField(max_length=200)
UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

# 关系
manufacturer = models.ForeignKey(Manufacture,
on_delete=models.CASCADE/PROTECT/SET_NULL/SET_DEFAULL,#联级删除,删除包含ForeignKey的对象
related_name='+',#不创建反向关系
related_query_name='',
limit_choices_to={'':''},
to_field= ,
db_constraint=True,
swappable=True,)

topping = models.ManyToManyField(Topping,
through='', #添加额外字段,模型,只能实例添加,用clear()删除关系
through_fields=('', ''),
)
wcg_membership = wcg.membership_set.get(group=3018) # 没有外键关联的一方

user = models.OneToOneField(User, parent_link=True) #相当于继承,返回父类的链接

# Meta
class Meta: # 通过内部模型提供元数据
ordering = ['-name']
abstract = True #抽象基类
proxy = True #代理,在代理中更改默认排序,默认管理器内容,但没有改原始内容
app_label = '' #应用程序之外的模型
db_table = ''
default_related_name = ''
get_latest_by = ['', '']
order_with_respect_to = ''
permissions = (('can_read', 'can_write'))
indexes = [models.Index(field=['name', name='name_index']),]
unique_together = (('', ''))
index_together = [['', '']]
verbose_name = ''

# 模型实例
self
@classmethod
@staticmethod
@property
__str__()
get_absolute_url()
class BookManager(models.Manager) #创建,自定义管理器
obj.refresh_from_db() #刷新
from django.core.exceptions import ValidationError #验证
try:
article.full_clean() #Model.clean_fields() clean() validate_unique()
except ValidationError as e:
pass
Model.get_FOO_display() #返回该字段的人类可读的值
Model.get_next/previous_by_FOO() #对于DataField,DataTimeField,返回日期前一个,下一个对象

# 重写
class blog(models.Model):
name = models.CharField(max_length=10)

def save(self, *args, **kw):
do_something()
super().save(*args, **kw)
do_something_else()

QuerySet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
content = models.TextField()

def __str__(self):
return self.name

class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()

class Entry(models.Model): #章节,条目
body_text = models.TextField()
blog = models.ForeignKey(Blog, related_name='entries', on_delete=models.CASCADE)
authors = models.ManyToMany(Author)

# 创建对象
b = Blog(name='django', author='wcg') b.save()
b.name = 'w' b.save()
# 一对多
entry = Entry.objects.get(pk=1)
wcg_blog = Blog.objects.get(name='wcg')
entry.blog = wcg_blog entry.save()
# 多对多
wcg = Author.objects.create(name='wcg')
a = Author.objects.create(name='a')
entry.authors.add(wcg, a)

# 检索对象,惰性
all_entries = Entry.objects.all()[:5]
Entry.objects.filter(pub_date__year/data/month/day=2006).exclude(pub_date__gte=datatime.date.today())
one_entry = Entry.objects.get(pk=1/id=1/id__exact=1)
__exact #精确匹配 __iexact 不区分大小写
__contains #包含
__startswith #开头
__endswith #结尾
__in=[]
__range()
__isnull=True
__regex=r'' #正则
# 方法
.reverse() #反转
.distinct() #去重
.values() #当迭代器使用,返回字典
.values_list()
.dates('pub_date', 'year')
.datatimes('pub_date', 'year', 'ASC/DESC')
.union() #合并
.intersection() #交集
.difference()
.select_related() # 缓存
.prefetch_related() # 和上相似,但策略不同
.defer() #不检索字段
.only() #只检索
.using() #使用别名
.select_for_update() #返回直到事务结束的查询集
.get_or_create()
.update_or_create()
.bulk_create() #高效的插入数据
.in_bulk([]) #获取list的值
.iterator()
.latest() #获取最新对象
.earliest() #获取最早
.first()
.last() #最后一个
if .exists() #是否存在

# 关系查找
Entry.objects.filter(blog__name='django')
Blog.objects.filter(entry__body_text__contains='wcg')
Blog.objects.filter(entry__authors__name='wcg'/entry__authors__name__isnull=True)
# 同一模型,不同字段比较
from django.db.models import F
Entry.objects.filter(comments__gt=F(('pingbacks')) * 2)
Entry.objects.filter(authors__name=F('blog__name'))
from datetime import timedelta
Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))

# 缓存
e = Entry.objects.select_related().get(id=2)
print(e.blog) #用缓存

# Q复杂查找
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005, 5, 2)) | ~Q(pub_date=date(2005, 5, 6))
)

# 删除对象
f = Blog.objects.get(pk=1)
f.delete()
remove(*obj)
clear() #删除所有对象

# 替换
set(*obj)

# 更新
Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

# 反向关系
b = Blog.objects.get(pk=1)
b.entry_set/entries.all() #返回blog所有的entry
b.entry_set.filter(headline__contains='Lennon')
b.entry_set.count()
# 多对多
e = Entry.objects.get(id=3)
e.authors.all() # Returns all Author objects for this Entry.
e.authors.count()
e.authors.filter(name__contains='John')

a = Author.objects.get(id=5)
a.entry_set.all() # Returns all Entry objects for this Author.

Advanced

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 执行SQL语句
Blog.objects.raw('SELECT * FROM django_blog')[0]
from django.db import connection
with connection.cursor() as cursor:
cursor.execute('')
row = cursor.fetchone()/fetchall()

# 事务
from django.db import transaction, IntegrityError #事务
@transaction.non_atomic_requests #
@transaction.atomic #原子性
def view(request):
pass
transaction.on_commit(do_something) #事务提交成功,执行操作
sid = transaction.savepoint()
try: #事务回滚
b.save()
transaction.savepoint_commit(sid)
except IntegrityError:
transaction.rollback()
transaction.savepoint_rollback(sid) #保存点回滚

# 聚合
from django.db.models import Avg, Max, Min, Sum, Count, StdDev, Variance
Book.objects.count()
Book.objects.aggregate(Avg('price'), Max('price'), Min('price')) #聚合,返回字典
{'price__avg': 34.35, 'price__max': Decimal('81.20')}
q = Book.objects.annotate(Count('authors', distinct=True)).order_by() #注释,每个对象多个属性,返回对象
q[0].authors__count
Author.objects.values('name').annotate(average_rating=Avg('book__rating'))
Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors')) #聚合注释
{'num_authors__avg': 1.66}

# 搜索
Author.objects.filter(name__unaccent__icontains='Helen')
Entry.objects.filter(body_text__search='cheese') #PostgreSQL
----------本文完,感谢您的阅读----------