增Create
1.保存
要创建对象,请使用模型类的关键字参数将其实例化,然后调用save()将其保存到数据库。
#方式一 Test模块常用 一个步骤中创建和保存对象
models.Entity.objects.create(c1='xx', c2='oo') # 增加一条数据,可以接受字典类型数据 **kwargs
#方式二
obj = models.Entity(c1='xx', c2='oo')
obj.save()
该save()方法没有返回值。如果模型具有一个AutoField自动递增的主键,则该自动递增的值将被计算并在您首次调用时保存为对象上的属性。
2.保存ForeignKey和ManyToManyField字段
一个博客功能的实例:
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
更新ForeignKey字段的工作原理与保存普通字段的方法完全相同,只需将正确类型的对象分配给相关字段即可。此示例更新blog
的属性 Entry
,假设的适当的实例Entry
和 Blog
已经保存到数据库。
from blog.models import Blog, Entry
entry = Entry.objects.get(pk=1)
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()
更新ManyToManyField作品的方式略有不同-使用 add()字段上的方法向关系中添加记录。本示例将Author
实例 添加joe
到entry
对象:
from blog.models import Author
joe = Author.objects.create(name="Joe")
entry.authors.add(joe)
要ManyToManyField一次性添加多个记录,请在的调用中包含多个参数 add(),如下所示:
john = Author.objects.create(name="John")
paul = Author.objects.create(name="Paul")
george = Author.objects.create(name="George")
ringo = Author.objects.create(name="Ringo")
entry.authors.add(john, paul, george, ringo)
3.保存指定字段
save()
在关键字arguments中传递了字段名称列表 update_fields
,则仅更新该列表中命名的字段。
product.name = 'Name changed again'
product.save(update_fields=['name'])
查Retrieve
1.查询所有对象
all_entries = Entry.objects.all()
该all()方法返回的QuerySet包含数据库中所有对象。
2.使用过滤查询特定对象
filter(**kwargs)
返回QuerySet包含与给定查找参数匹配的新的对象。
exclude(**kwargs)
返回一个新的QuerySet包含对象,这些对象与给定的查找参数不匹配。
Entry.objects.filter(name='foot')
Entry.objects.exclude(name='foot')
链接过滤器
Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime.date(2005, 1, 30)
... )
过滤后的QuerySet
s是唯一的
每次过滤都会创建一个单独的,独特的QuerySet,可以存储,使用和重用。
q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.date.today())
q3 = q1.filter(pub_date__gte=datetime.date.today())
这三个QuerySets
是分开的。第一个是QuerySet包含所有条目的基础 ,这些条目包含以“ What”开头的标题。第二个是第一个的子集,带有附加条件,该条件不包括pub_date
今天或将来的记录。第三个是第一个的子集,带有一个附加条件,该条件仅选择pub_date
今天或将来的记录。首字母QuerySet(q1
)不受优化过程的影响。
3.查询单个对象
如果您知道只有一个对象与您的查询匹配,则可以在Manger上使用get()直接返回该对象 。
one_entry = Entry.objects.get(pk=1)
如果没有与查询匹配的结果,get()将引发DoesNotExist
异常。在上面的代码中,如果没有Entry
主键为1的对象,则Django会引发Entry.DoesNotExist
。
同样,如果有多个项目与get()查询匹配,它将引发MultipleObjectsReturned。
返回指定字段
values() 接收可选的位置参数*fields,它指定SELECT 应该限制哪些字段。如果指定字段,每个字典将只包含指定的字段的键/值。如果没有指定字段,每个字典将包含数据库表中所有字段的键和值。
# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
[<Blog: Beatles Blog>]
# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]
4.进阶查询之神奇的双下划线
· 大于、小于
Entry.objects.filter(id__gt=1) # 获取id大于1的值
Entry.objects.filter(id__gte=1) # 获取id大于等于1的值
Entry.objects.filter(id__lt=10) # 获取id小于10的值
Entry.objects.filter(id__lte=10) # 获取id小于10的值
Entry.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
#SELECT * FROM app_entry WHERE id <= 10;
· 成员判断in
Entry.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
Entry.objects.exclude(id__in=[11, 22, 33]) # not in
##SELECT * FROM app_entry WHERE id in (11,22,33);
· 模糊包含contains
Entry.objects.filter(name__contains="ven")
Entry.objects.filter(name__icontains="ven") # icontains大小写不敏感
Entry.objects.exclude(name__icontains="ven")
#SELECT ... WHERE name LIKE '%ven%';
· 其他匹配
startswith,istartswith, endswith, iendswith,
· 范围range
Entry.objects.filter(id__range=[1, 2]) # 范围bettwen and
· 排序order by
Entry.objects.filter(name='seven').order_by('id') # asc
Entry.objects.filter(name='seven').order_by('-id') # desc
· 分组group by
models.Tb.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT app_tb.id", COUNT(app_tb.num) AS c FROM app_tb WHERE app_tb.c1 = 1 GROUP BY app_tb.id
· limit 、offset
#返回前5个对象():LIMIT 5
Entry.objects.all()[:5]
#返回第六个到第十个对象():OFFSET 5 LIMIT 5
Entry.objects.all()[5:10]
要检索单个对象而不是列表,请使用简单索引而不是切片。例如,在按标题按字母顺序对条目进行排序之后,这将返回数据库中的第一个:SELECT foo FROM bar LIMIT 1
Entry.objects.order_by('headline')[0]
这大致相当于:
Entry.objects.order_by('headline')[0:1].get()
· 计数
Entry.objects.filter(name='seven').count()
· 是否为空
Entry.objects.filter(pub_date__isnull=True)
· 时间 year / month / day / week_day / hour / minute / second / gt: 年 / 月 / 日 / 周 / 时 / 分 / 秒 /
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__month__gte=6)
Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__week_day=2)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__minute__gte=29)
Event.objects.filter(time__second=2)
删Delete
删除掉单个数据
Entry.objects.get(id=4).delete()
删除指定条件的数据
Entry.objects.filter(name='seven').delete()
删除所有数据
Entry.objects.all().delete()
改Update
改既可以用save方法,也可以用update方法。其区别在于save方法不仅可以更新数据中现有对象数据,还可以创建新的对象。而update方法只能用于更新已有对象数据。一般来说,如果要同时更新多个对象数据,用update方法更合适。
利用save方法更新
obj = Entry.objects.get(id=1)
obj.name = '111'
obj.save()
利用update方法更新
obj = Entry.objects.get(id=1).update(name='new title')
利用update方法更新多条数据
Entry.objects.filter(name__icontains='python').update(name='Django')
常用操作
<1> all(): 查询所有结果
<2> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
<3> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
<4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
<5> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
<6> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
<7> order_by(*field): 对查询结果排序
<8> reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
<9> distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
<10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
<11> first(): 返回第一条记录
<12> last(): 返回最后一条记录
<13> exists(): 如果QuerySet包含数据,就返回True,否则返回False