Django特别篇-数据库API-查询篇

版权声明:笔记随便写写 https://blog.csdn.net/aaxin_666/article/details/86551688

进行查询

打开model.py

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

现在我们来详细看一下这些东西吧

  1. 创建了3个模型类,博客,作者,实体(每篇博客下的对应的其余文章),类似于在CSDN首页(对应着博客类,),你可以看到很多具体的博客(entry),每个博客有名字等具体内容(author)
  2. 每个模型类都关联这一个对应的数据库的表,其中的变量对应的是数据库表中的字段
  3. 关系模型数据库,表与表的关联方式,,博客类与author作者类就是创建了两个字段,没什么可说的,重点是entry类,在首页,每个小版块的博客都是一篇具体的博客,那么开发人员考虑的是这个小博客具体放在哪个页面上,所有这里应该一对多的关系,就是说一个博客页面可以放很多小的博客板块,那么通过这个关联关系,我们可以在python代码中找出所有首页的博客,再看author这个字段,
authors = models.ManyToManyField(Author)

ManyToMany表示的是多对多的关系,就是说在
在这里插入图片描述大概像是这个样子,ps:
打开命令行工具:python manage.py shell

from blog.models import Blog
 b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

创建了一个博客类的对象,也映射到了数据库当中,save()就是讲当前的结果保存
保存一个外键和多对多关系

>>> 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()

这里说的是更新一个外键
如何增加一个多对多关系呢?

>>> 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)

这是增加多个多对多关系的,这是两边都有映射关系存在的

查询集 QuerySets

>>> all_entries = Entry.objects.all()

查询结果为查询集
例子:

Entry.objects.filter(pub_date__year=2006)
Entry.objects.all().filter(pub_date__year=2006)

get

>>> one_entry = Entry.objects.get(pk=1)

filter

过滤出符合条件的结果

>>> 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())

exclude

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')

类似于

SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')

从这个词的英文意思 ‘ 排除 ’也可以看得出。
实际上,只要 你在shell 命令行的时候,打开你的数据库日志文件记录,那么你就可以看到对应的语句转换成SQL语句执行的具体过程,这样更加直观

限制查询

Entry.objects.all()[:5]

相对应的SQL语句是

select * from entry OFFSET 5 LIMIT 5:

注意,如果索引越界,就会报错

exact

Entry.objects.get(headline__exact="Cat bites dog")

SQL:

SELECT ... WHERE headline = 'Cat bites dog';

iexact -case-insensitive

不区分大小写

Blog.objects.get(name__iexact="beatles blog")

contains

Entry.objects.get(headline__contains='Lennon')

SQL

SELECT ... WHERE headline LIKE '%Lennon%';

F()对象

Django提供F表达式来允许这样的比较。F()的实例作为查询中的模型字段的引用。然后可以在查询筛选器中使用这些引用来比较同一个模型实例上两个不同字段的值。
例如,要查找所有评论多于pingbacks的博客条目的列表,我们构造一个F()对象来引用

>>> from django.db.models import F
>>> Entry.objects.filter(n_comments__gt=F('n_pingbacks'))

再比如:

Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))

这个表示的是评分数量小于评论数与条目数总和

Caching and QuerySets

每个QuerySet都包含一个缓存来最小化数据库访问。了解它的工作原理将使您能够编写最有效的代码。在新创建的QuerySet中,缓存是空的。当查询集第一次被求值时(因此会发生数据库查询),Django将查询结果保存在QuerySet s缓存中,并返回显式请求的结果(例如,如果正在迭代QuerySet,则返回下一个元素)。QuerySet的后续评估重用缓存的结果。请记住这种缓存行为,因为如果没有正确使用查询集,它可能会影响您。例如,下面将创建两个查询集,对它们求值,并将它们丢弃

>>> queryset = Entry.objects.all()
>>> print([p.headline for p in queryset]) # Evaluate the query set.
>>> print([p.pub_date for p in queryset]) # Re-use the cache from the evaluation

Q对象的复杂查找

关键字参数查询——在filter()等中——是“和”ed一起的。如果需要执行更复杂的查询(例如,带有或语句的查询),可以使用Q对象。
Q对象(django.db.models.Q)是用于封装关键字参数集合的对象。这些关键字参数在上面的“字段查找”中指定。
例如,这个Q对象封装了一个LIKE查询:

from django.db.models import Q
Q(question__startswith='What')

Q对象可以使用&和|操作符组合。当一个操作符用于两个Q对象时,它会产生一个新的Q对象。
例如,该语句生成一个Q对象,该对象表示两个“question__startswith”查询的“OR”:

Q(question__startswith='Who') | Q(question__startswith='What')
WHERE question LIKE 'Who%' OR question LIKE 'What%'

delete

删除对象,不想说

复制对象模型

尽管没有用于复制模型实例的内置方法,但是可以轻松地使用复制的所有字段的值创建新实例。在最简单的情况下,您可以将pk设置为None。使用我们的博客示例

blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1

blog.pk = None
blog.save() # blog.pk == 2
entry = Entry.objects.all()[0] # some previous entry
old_authors = entry.authors.all()
entry.pk = None
entry.save()
entry.authors.set(old_authors)

一次更新对个对象

在查询集后面加上update方法

>>> b = Blog.objects.get(pk=1)

# Change every Entry so that it belongs to this Blog.
>>> Entry.objects.all().update(blog=b)

relation object 关系对象

One-to-many relationships

如果一个模型有一个外键,那么该模型的实例将通过模型的一个简单属性访问相关(外)对象

>>> e = Entry.objects.get(id=2)
>>> e.blog # Returns the related Blog object.
>>> e = Entry.objects.get(id=2)
>>> e.blog = some_blog
>>> e.save()

如果一个字段有has=null ,那么你就可以设置null值去删除关系

>>> e = Entry.objects.get(id=2)
>>> e.blog = None
>>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"

在数据库表的建立阶段就要设置这个属性

关系对象的其他方法

  1. add
  2. create
  3. remove
  4. clear
  5. set
    就是表面意思,累了,不想翻译了

多对多的关系 Many-to-many relationships

多对多关系的两端都可以获得对另一端的自动API访问。该API的工作原理类似于上面的“向后”一对多关系。
例子:

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()

方法的调用一样

a = Author.objects.get(id=5)
a.entry_set.set([e1, e2])
a.entry_set.set([e1.pk, e2.pk])

一对一的关系 One-to-one relationships

一对一关系非常类似于多对一关系。如果您在模型上定义一对一字段,那么该模型的实例将可以通过模型的一个简单属性访问相关对象
一对一关系中的相关模型也可以访问管理器对象,但该管理器表示单个对象,而不是对象的集合

class EntryDetail(models.Model):
    entry = models.OneToOneField(Entry, on_delete=models.CASCADE)
    details = models.TextField()

ed = EntryDetail.objects.get(id=2)
ed.entry # Returns the related Entry object.

e = Entry.objects.get(id=2)
e.entrydetail # returns the related EntryDetail object

如果没有分配这种关系,会报错
然后:

e.entrydetail = ed

会产生对应关系

ps:学习是痛苦的

猜你喜欢

转载自blog.csdn.net/aaxin_666/article/details/86551688
今日推荐