Django 学习 笔记

Django 一、模型models 继承django.db.models.Model

1.模型字段 / 模型字段选项参考:

官网:https://docs.djangoproject.com/zh-hans/3.2/ref/models/fields/#common-model-field-options

2.模型Meta选项(定义模型类的属性):

csdn: https://blog.csdn.net/bbwangj/article/details/79967858

官网:https://docs.djangoproject.com/zh-hans/3.2/ref/models/options/

3.模型属性

Manger 无自定义的Manger ,默认是Objects,是Django模型和数据库查询操作之间的接口。通过模型类来访问,必能通过模型实例来访问。 (表级操作)

4.模型方法 (行级操作)

在模型中添加自定义方法,或者复写原来的方法。

_str ()

get_absolute_url()

可以在save/delete前后,做些额外的事情

Save()

Delete()

def save(self, *args, **kwargs):

do_something()

super().save(*args, **kwargs) # Call the "real" save() method.

do_something_else()

5.模型继承

(1)抽象基类:

创建基类,使用meta中的abstract,不会创建数据表,继承该基类,会获取该类中的字段

class Meta:

abstract = True

(2)多表继承

每个子类模型创建一张新表。

(3)代理模型

修改/添加模型的方法。继承模型类,通过Meta的proxy,设置代理模型。MyPerson和Person使用同一张表

class MyPerson(Person):

class Meta:

proxy = True

def do_something(self):
    # ...
    pass

(4)多重继承

Django 二、执行查询

1.创建对象 (save/create)

s = Student(name='myName')

s.save()

或一步创建

Blog.objects.create(name="Blog1", tagline="this is a blog1.")

2.修改对象

a = Blog.objects.all().first()

a.name = 'Blog2'

a.save()

保存ForeignKey字段

a.student = Student.object.get(id=1)

a.save()

保存ManyToManyField字段

b1=Blog.objects.get(id=2)

b2=Blog.objects.get(id=3)

b3=Blog.objects.get(id=4)

s.blog.add(b1,b2,b3)

3.检索对象

QuerySet代表来自数据库中对象的一个集合, 类似于select语句

Filter 给定参数,缩小查询结果量。类似于where或limit

(1)查全部:Student.objects.all()

(2)过滤器检索

filter(**kwargs) 满足给定查询参数

exclude(**kwargs) 不满足给定查询参数

链式过滤器:student.objects.filter(xxxx).exclude(xxxxxx).filter(xxxxxx)

每个QuerySet都是唯一的:

q1=student.objects.filter(条件1) 满足条件1的querySet

q2=q1...exclude(条件2) 满足条件1和不满足条件2的querySet

q3=q1.filter(条件3) 满足条件1和条件3的querySet

QuerySet是惰性的:创建QuerySet不会引发数据库活动,只有被计算是才执行查询操作

q=student.objects.filter(xxxx)

q=q.exclude(xxxxxx)

q=q.filter(xxxxxx)

Print(q) 开始执行查询

(3)使用get()检索单个对象

没有满足条件时,抛DoesNotExist异常

匹配多个对象,抛MultipleObjectsReturned异常

(4)其他QuerySet方法

Order_by()

Reverse()

Distinct()

Values()

Value_list()

Select_related()

Union() 并集

Intersection() 交集

Difference() 差集

......

官网:https://docs.djangoproject.com/zh-hans/3.2/ref/models/querysets/#queryset-api

(5)限制QuerySet条目数

对QuerySet进行切片操作,禁止对其进行进一步排序或过滤

Student.objects.all[:5]

Student.objects.all[5:10]

(6)字段查询

以关键字参数传递给QuerySet方法,格式:field__lookuptype=value

exact :关键字参数不包含__,类型会指定为exact。

Blog.objects.get(id__exact=2)

Blog.objects.get(id=2)

iexact:不分大小写的匹配

Blog.objects.get(name__iexact='blog1')

Contains: 大小写敏感的包含测试

Blog.objects.get(name__contains='b') ===>like '%b%'。 会自动转义其中的%和下划线

startswith, endswith: 以......开头和以......结尾的查找。

istartswith, iendswith: 以......开头和以......结尾的查找,大小写不敏感。

In/gt/gte/lt/lte/range/date/year/month/day/isnull/regex/iregex.........

官网:https://docs.djangoproject.com/zh-hans/3.2/ref/models/querysets/#field-lookups

(7)跨关系查询

Entry.objects.filter(blog__name='Blog1')

Entry.objects.filter(blog__name_contains='Blog')

(8)跨多值关联

要注意链式过滤器的结果

(9)过滤器为模型指定字段 (F表达式)

模型字段值与另一个字段进行比较

F表达式,支持对F()对象进行加减乘除等操作,F()中也能用__,关联关系查询,对于date/datetime可以加减一个timedelta对象,支持位操作。

Entry.objects.filter(updateTime__gt=F('addTime')+timedelta(day=3))

(10)主键(pk)查询快捷方式

Student.object.get(id__exact=2)

Student.object.get(id=2)

Student.object.get(pk=2)

关于用id查询的都可以用pk代替

(11)缓存和QuerySet

尽量保存QuerySet,来复用,触发计算全部的查询结果集,保证结果填入缓存。之后用的都是缓存中的。

以下动作可以触发计算全部的查询结果集:

[i for i in queryset]

bool(queryset)

i in queryset

List(queryset)

4.查询JSONField

使用JSONField字段, 可以使用JSONField来准确查找数据。

创建:

from django.db import models

class Dog(models.Model):

name = models.CharField(max_length=200)

data = models.JSONField(null=True)

def __str__(self):
    return self.name

保存和查询None值:

Dog.objects.create(name='Max',data=None)

Dog.objects.filter(data__isnull=True). ===>Max

可以将字典中的key或数组的index作为查询名,进行Json内部数据的查询。

Dog.objects.create(name='Rufus', data={

... 'breed': 'labrador',

... 'owner': {

... 'name': 'Bob',

... 'other_pets': [{

... 'name': 'Fishy',

... }],

... },

... })

<Dog: Rufus>

Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})

<Dog: Meg>

Dog.objects.filter(data__breed='collie')

<QuerySet [<Dog: Meg>]>

Dog.objects.filter(data__owner__name='Bob')

<QuerySet [<Dog: Rufus>]>

Dog.objects.filter(data__owner__other_pets__0__name='Fishy')

<QuerySet [<Dog: Rufus>]>

包含与键查找:

Contains: 查询data中包含{'owner':'Bob'}的Dog

Dog.objects.filter(data__contains={'owner': 'Bob'})

Contained_by: 查询data中包含{'owner':'Bob'}或{'breed':'collie'}的Dog

Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})

Has_key: 查询data的key中有owner的Dog

Dog.objects.filter(data__has_key='owner')

Has_keys:查询data的key中有owner和breed的Dog

Dog.objects.filter(data__has_keys=['breed', 'owner'])

Has_keys:查询data的key中有owner或breed的Dog

Dog.objects.filter(data__has_any_keys=['owner', 'breed'])

5.通过Q对象完成复杂查询

Q对象(django.db.models.Q)可以压缩关键字参数集合,通过&,|,括号,~连接起来。

查询函数filter(),exclude(),get()可以接受一个或多个Q对象参数

如果有Q对象,必须位于所有关键字参数之前。

Poll.objects.get(

Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),

question__startswith='Who',

)

6.比较对象

使用==,实际比较的是两个模型实例的主键值。

some_entry == other_entry

some_entry.id == other_entry.id

7.删除对象

e.delete(),删除对象,并返回被删除对象的个数和对象类型的字典。

querySet的delete()方法,批量删除querySet中的对象,但是要注意不会调用复写的delete()方法。

关联对象也会删除,由外键的on_delete参数指定。

8.一次修改多个对象

querySet的update()方法,批量更新数据,不会调用模型的save(),可以使用F表达式

Entry.objects.all().update(number_of_pingbacks=F('number_of_pingbacks') + 1)

9.关联对象

模型中定义了关联关系(ForeignKey,OneToOneField,ManyToManyField),可以快速访问关联对象。

Blog中有多个Entry

(1)一对多关联:

正向访问:

e = Entry.objects.get(id=2)

e.blog = some_blog

e.save()

反向访问:

b = Blog.objects.get(id=1)

b.entry_set.all() # Returns all Entry objects related to Blog.

b.entry_set is a Manager that returns QuerySets.

b.entry_set.filter(headline__contains='Lennon')

b.entry_set.count()

关联对象的其他方法:

Add(obj1,obj2......) 添加

Create(**kwargs)。 创建一个新对象,并加入关联对象集合中

Remove(obj1,obj2,...) 从关联对象集合中删除

Clear() 清空关联对象集合

Set(objs) 替换关联对象集合. b.entry_set.set([e1,e2])

(2)多对多关联:

可以加上'_set'

....

通过设置related_name

(3)一对一关联

Django 三、聚合

1.在QuerySet上生成聚合

Aggregate() 输出值是QuerySet的终端子句,字典

from django.db.models import Avg

Book.objects.all().aggregate(Avg('price'))

简化为

Book.objects.aggregate(Avg('price'))

Book.objects.aggregate(average_price=Avg('price')) 提供聚合值的名称

聚合函数:

AVg, Count, Max, Min, StdDev, Sum, Variance

官网:https://docs.djangoproject.com/zh-hans/3.2/ref/models/querysets/#aggregation-functions

2.为QuerySet中的每一条目生成聚合

Annotate()子句 注解 , 输出值是QuerySet

Book和Author是多对多的关系

Book.object.annotate(Count('authors')) 查询出各个书的作者的数量

提供聚合值的名称

Book.objects.annotate(num_authors=Count('author'))

3.组合多个聚合

使用distinct参数

q = Book.objects.annotate(Count('authors', distinct=True), Count('store', distinct=True))

q[0].authors__count

2

q[0].store__count

3

4.和filter, exclude连用,进行复杂的查询操作,,不过要注意顺序

相关推荐
Wx-bishekaifayuan3 小时前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
小码的头发丝、10 小时前
Django中ListView 和 DetailView类的区别
数据库·python·django
知识的宝藏11 小时前
Django中间件应该怎么使用
中间件·django
千澜空11 小时前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
竹笋常青12 小时前
《流星落凡尘》
django·numpy
coberup17 小时前
django Forbidden (403)错误解决方法
python·django·403错误
过期动态1 天前
详解Python面向对象程序设计
开发语言·python·pycharm·django
阿乾之铭1 天前
通过Django 与 PostgreSQL 进行WEB开发详细流程
python·postgresql·django
春天的菠菜1 天前
【django】Django REST Framework (DRF) 项目中实现 JWT
后端·python·django·jwt
千里码aicood2 天前
[含文档+PPT+源码等]精品基于Python实现的django房屋出租系统的设计与实现
开发语言·python·django