Django QuerySet(一)

Qs能被执行的情况:

迭代,切片,缓存/序列化,repr,len,list,bool

Qs 其实是被设计成链式的调用,因为他调用后返回Qs,这点非常酷。

filter(**kwargs)

可以指定多个条件,多个条件之间用AND拼接,这个最常用,但是如果对于复杂场景,可以用Q表达式

In [11]: models.Person.objects.filter(pk=1).first().first_name
Out[11]: 'wz'

exclude(**kwargs)

这个表达式主要转换成NOT

In [12]: persons = models.Person.objects.exclude(first_name='y')
In [13]: for person in persons:
    ...:     print(person.last_name)
    ...:     zx

order_by(*fields)

排序其实有两个地方可以指定,一个是在Meta类里,另外一个就是oder_by,参数可以跟多个,比如

In [14]: persons = models.Person.objects.exclude(first_name='y').order_by('-id')
In [15]: for person in persons:
    ...:     print(person.last_name)
    ...:     
zx

如果需要倒序,就如看到的一样,前面加一个”-”就可以,非常方便。也可以跟多个order_by表达式,如

In [16]: persons = models.Person.objects.order_by('-id').order_by('first_name')
In [17]: for person in persons:
    ...:     print(person.last_name)
    ...:     
111
222
xx
zx
fafa

有一些方法不返回Qs, 而且也不用缓存

get(**kwargs)

这个调用需要注意,结果多于一个会报异常,没有结果也会报异常,所以不怎么用这个函数,倒是喜欢用first()。不过如果对于这些异常能hold住,用这个是比较合适的。

In [18]: persons = models.Person.objects.filter(pk=100).get()
DoesNotExist                              Traceback (most recent call last)
<ipython-input-18-d366ca5c185a> in <module>()
----1 persons = models.Person.objects.filter(pk=100).get()

~/.virtualenvs/env32/lib/python3.6/site-packages/django/db/models/query.py in 

get(self*args, **kwargs)

    378             raise self.model.DoesNotExist(
    379                 "%s matching query does not exist." %
--380                 self.model._meta.object_name
    381             )
    382         raise self.model.MultipleObjectsReturned(
DoesNotExist: Person matching query does not exist.

create(**kwargs)

其实创建有两种方法,直接实例化对象就是一种

In [21]: person = models.Person(first_name='xu', last_name='jiang')
In [22]: person.save()
In [23]: person.last_name
Out[23]: 'jiang'

需要注意的是这里需要去调用下save方法主动保存到数据库中

另外一种就是要介绍的用manager的create方法

In [19]: person = models.Person.objects.create(first_name='chen'

last_name='jie')

In [20]: person.last_name
Out[20]: 'jie'

这两种写法是等价的

这里需要注意,如果我们指定主键为一个已经存在的值,那会去更新

In [24]: person = models.Person(first_name='xu', last_name='jiang'id=1)
In [25]: person.save()

如果需要强制插入呢,save()方法也提供了一个参数

In [26]: person.save(force_insert=True)
IntegrityError                            Traceback (most recent call last)

~/.virtualenvs/env32/lib/python3.6/site-packages/django/db/backends/utils.py 

in execute(self, sql, params)

     63             else:
---64                 return self.cursor.execute(sql, params)
     65 

~/.virtualenvs/env32/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py 

in execute(self, query, params)

    327         query = self.convert_query(query)
--328         return Database.Cursor.execute(self, query, params)
    329 
IntegrityError: UNIQUE constraint failed: myapp_person.id

这种情况如果重复的话,就报出异常

get_or_create(defaults=None, **kwargs)

这个调用更像是get和create的结合,在一定场景中有用

In [28]: person = models.Person.objects.get_or_create(first_name='hello',last_name='world')

{'db.statement''INSERT INTO "myapp_person" ("first_name", "last_name") VALUES (%s, %s)'

duration 0:00:00.034630

可以看到它转换成了INSERT语句,对于存在的情况再试下

In [29]: person = models.Person.objects.get_or_create(first_name='hello',last_name='world')

{'db.statement''SELECT "myapp_person"."id", "myapp_person"."first_name", "myapp_person"."last_name" FROM 

"myapp_person" WHERE ("myapp_person"."first_name" = %s AND "myapp_person"."last_name" = %s)'

duration 0:00:00.000182

好,这次就到这里,简单总结下,我们介绍了几个django下常用的链式调用,比如filter,order_by等,他们调用都非常简单。

Happy hacking

暂无评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

备案号:浙ICP备15006402号-2 备注:博客君在0.071里共执行41个查询, 总共占用内存 8.31MB