第十八 django及ORM操作

一、项目及ORM操作

1.添加新项目

python manage.py startapp blog

2.配置数据库类 models.py

from django.db import models

# Create your models here.
class Blog(models.Model):
    name = models.CharField(max_length=100)
    tag_line = models.TextField()

    def __str__(self):
        return self.name

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

    def __str__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    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

3.配置settings

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #'app01.apps.App01Config',
    'blog',
]

4.运行创建数据库py文件

运行报错,是因为url里面路径,涉及到以前的项目,应该注释

4.2.运行创建数据库py文件

4.3.运行创建表

4.4.查看数据库

5.blog 的项目

二、ORM 相关操作

1.通过命令插入blog项

1.1.原内容

 1.2.通过命令插入新的

from blog.models import Blog
b = Blog(name="美发品",tag_line='再也没有一天,是曾经的某一天')
b.save()

1.3.查看结果

2.修改外键关联的表

2.1.查看原始内容

 

 2.2.将“冬天会下雪”改掉

from blog.models import Entry
entry = Entry.objects.get(pk=1)
ckl_blog = Blog.objects.get(name="美发品")
entry.blog = ckl_blog
entry.save()

2.3.查看结果

没看出结果,呜呜呜~~~~

3.修改多对多关联的表

3.1.修改内容,添加作者

from blog.models import Author
ckl = Author.objects.create(name='wukaka')
entry.authors.add(ckl)

 3.2.查看作者

4.单表内容查询

all_entry = Entry.objects.all()  #查询所有
print(all_entry)
<QuerySet [<Entry: 春天花会开>, <Entry: 冬天会下雪>, <Entry: 暴雪将至>, <Entry: 天晴脚疼>]>

Entry.objects.filter(pub_date__year=2016)  #查询出版年份在2016年
<QuerySet [<Entry: 暴雪将至>, <Entry: 天晴脚疼>]>
Entry.objects.all().filter(pub_date__year=2017) #同上查询出版年在2017年 <QuerySet [<Entry: 春天花会开>, <Entry: 冬天会下雪>]>

Entry.objects.all()[:3] #查询前3条数据
<QuerySet [<Entry: 春天花会开>, <Entry: 冬天会下雪>, <Entry: 暴雪将至>]>


Entry.objects.all()[2:3]  #查询区间
<QuerySet [<Entry: 暴雪将至>]>


Entry.objects.order_by('headline')[0] #排序,查询第一个
<Entry: 冬天会下雪>


Entry.objects.get(pk=1) #查询一条值,主键为1
<Entry: 春天花会开>


Entry.objects.filter(pub_date__lte='2017-01-01') #查询日期小于2017-01-01
<QuerySet [<Entry: 暴雪将至>, <Entry: 天晴脚疼>]>


Entry.objects.get(headline__exact="冬天会下雪") #查询标题等于这个
<Entry: 冬天会下雪>


Entry.objects.get(headline__iexact="冬天会下雪") #同上,不区分大小写
<Entry: 冬天会下雪>

Entry.objects.get(body_text__contains='虚幻') #查询内容匹配'虚幻'的
<Entry: 暴雪将至>

 5.联合查询

5.1.配置显示内容

修改admin

from django.contrib import admin
from blog import models

# Register your models here.

class BlogAdmin(admin.ModelAdmin):
    list_display = ('blog','headline','body_text','pub_date','mod_date','n_comments','n_pingbacks')

admin.site.register(models.Author)
admin.site.register(models.Blog)
admin.site.register(models.Entry,BlogAdmin)

5.2.查看内容

5.3.查询Entry所属板块包含“风雨中”

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models

from django.db.models import F
obj = models.Entry.objects.get(blog__name__contains="风雨中")
print(obj)

结果:

暴雪将至

5.4.查询所有的“n_comments”小于"n_pingbaks"

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models

from django.db.models import F
# obj = models.Entry.objects.get(blog__name__contains="风雨中")
# print(obj)
objs = models.Entry.objects.filter(n_comments__lt=F("n_pingbacks"))
print(objs)

查询结果:

<QuerySet [<Entry: 暴雪将至>, <Entry: 不想就是不想>]>

 6.Caching and QuerySets

每个QuerySet都包含一个缓存来最小化数据库访问。 了解它的工作原理将允许您编写最高效的代码。

在新创建的QuerySet中,缓存是空的。 第一次对QuerySet进行评估 - 并因此发生数据库查询 - 查询结果将存储在QuerySet的缓存中,并返回已经明确请求的结果(例如,如果正在迭代QuerySet,则返回下一个元素)。 QuerySet的后续评估将重新使用缓存的结果。

记住这个缓存行为,因为它不能正确使用。 例如,下面将创建两个QuerySets,对它们进行评估,然后将其丢弃:

print([e.headline for e in Entry.objects.all()])
print([e.pub_date for e in Entry.objects.all()])

这意味着相同的数据库查询将执行两次,有效地加倍你的数据库负载。 此外,这两个列表可能会添加到相同的数据库记录中,因为它们可以添加到第二个或第二个请求中。

为了避免这个问题,只需保存QuerySet并重用:

queryset = models.Entry.objects.all()
print([p.headline for p in queryset])
print([p.headline for p in queryset])

结果:

['我的欲望很多', '回忆中', '暴雪将至', '时间和雨蛙', '不想就是不想']
['我的欲望很多', '回忆中', '暴雪将至', '时间和雨蛙', '不想就是不想']

当QuerySets没有被缓存时

查询集并不总是隐藏他们的结果。 当仅评估部分查询集时,将检查缓存,但未填充,则不会缓存查询返回的项目。 具体来说,这意味着将查询集限制为数组切片或索引将不会填充缓存。

例如,重复获取查询集中的某个索引

queryset = models.Entry.objects.all()
print(queryset[4])
print(queryset[4])

查询结果:

不想就是不想
不想就是不想

但是,如果整个查询集已经被评估,缓存将被检查:

queryset = models.Entry.objects.all()
[entry for entry in queryset]
print(queryset[4])
print(queryset[4])

结果:

不想就是不想
不想就是不想

 7.Complex lookups with Q objects(复杂查询)

关键字参数查询 - 在filter()等 - “和”在一起。 如果您需要执行更复杂的查询(例如,使用OR语句的查询),则可以使用Q对象。

Q对象(django.db.models.Q)是一个用来封装关键字参数集合的对象。 这些关键字被指定为上面的“字段查找”。

7.1.例如,这个对象封装了一个LIKE查询:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os

from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models
from django.db.models import F

from django.db.models import Q
obj = models.Entry.objects.filter(
    Q(blog__name__contains="过去岁月")
)
print(obj)

查询结果:

<QuerySet [<Entry: 回忆中>, <Entry: 不想就是不想>]>

 7.2. and  查询

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models
from django.db.models import F

from django.db.models import Q

obj = models.Entry.objects.filter(
    Q(n_comments__lt=F("n_pingbacks")),Q(pub_date__gt="2017-03-05")
)
print(obj)

查询结果:

<QuerySet [<Entry: 不想就是不想>]>

7.2. or 查询

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models
from django.db.models import F

from django.db.models import Q
obj = models.Entry.objects.filter(
    Q(n_comments__lt=F("n_pingbacks")) | Q(pub_date__gt="2017-09-05")
)

print(obj)

结果:

<QuerySet [<Entry: 我的欲望很多>, <Entry: 回忆中>, <Entry: 暴雪将至>, <Entry: 不想就是不想>]>

 8.更新数据

原数据:

n_pingbacks 自增1:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models
from django.db.models import F

from django.db.models import Q
obj = models.Entry.objects.update(n_pingbacks=F("n_pingbacks")+1)

查看结果:

 9.复合查询

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
from django.core.wsgi import get_wsgi_application
os.environ["DJANGO_SETTINGS_MODULE"] = "dj16.settings"
import django
django.setup()

from blog import models
from django.db.models import F
from django.db.models import Q


from django.db.models import Avg,Min,Max,Sum,Count
print(models.Entry.objects.all().aggregate(
    Avg('n_pingbacks'),Sum('n_pingbacks'),Min('n_pingbacks'),Max('n_pingbacks')
))

from fly import models as book_model
pub_obj = book_model.Publisher.objects.last()
print(pub_obj.name,pub_obj.book_set.select_related()) #反向关联查询

pub_objs = book_model.Publisher.objects.annotate(book_num=Count('book'))
for publisher in pub_objs:
    print(publisher.book_num)

查询结果:

{'n_pingbacks__avg': 6.8, 'n_pingbacks__sum': 34, 'n_pingbacks__min': 4, 'n_pingbacks__max': 10}
猫狗出版社 <QuerySet [<Book: <梦的奥秘>>, <Book: <陳の夏休み>>, <Book: <老毛上山>>]>
4
1
3
3

 

posted @ 2017-12-13 10:39  ckl893  阅读(163)  评论(0编辑  收藏  举报