一、django db models结构
django db models 属于django db的一部分。主要包括四部分:
1. models
2. querySet
3. query
4. manager
1. models。
models定义在djang/db/models/base.py中,一些比较重要的类:
ModelBase |
ModelBase是一个元类,继承于type,通过覆盖__new__方法动态创建Model类型,在Model中通过__metaclass__使用它。 |
ModelState |
A class for storing instance state |
Model |
Mode就是具体的django models,一般我们自定义的模型都需要继承于它,比如: from django.db import models
class Message(models.Model):
recipient = models.ForeignKey(User, verbose_name=u"收件人", related_name="message_recipients_set", db_index=True) |
|
|
2.querySet
querySet定义在django/db/models/query.py,ORM的核心API定义在这里面 , 一些比较重要的类:
QuerySet |
querySet是最核心的类,既表示返回的结果又能在结果上继续执行查询。当执行 Message.objects.filter(id=12020231) 返回的就是QuerySet |
ValuesQuerySet |
调用querySet的values()返回此对象 m = Message.objects.filter(id=12020231)
m.values()
输出: [{'status': 0, 'category': 12, 'buyable': 0, 'photo_id': 309867L...}] |
ValuesListQuerySet |
|
DateQuerySet |
|
EmptyQuerySet |
|
RawQuerySet |
|
get_cached_row() |
|
insert_query() |
|
|
|
QuerySet定义了很多常用的查询接口:
- iterator
- aggregate
- count
- get
- create
- get_or_create
- latest
- delete
- update
- exists
- values
- filter
- exclude
- using
具体的查询SQL是委托给self.query产生的,请看filter方法的具体实现:
def _filter_or_exclude(self, negate, *args, **kwargs):
if args or kwargs:
assert self.query.can_filter(), \
"Cannot filter a query once a slice has been taken."
clone = self._clone()
if negate:
clone.query.add_q(~Q(*args, **kwargs))
else:
clone.query.add_q(Q(*args, **kwargs))
return clone
3. query定义在djabgo/db.models/sql/query.py中,负责为QuerySets创建sql语句,里面定义了两个重要的类型
Query
A single SQL query.
RawQuery
A single raw SQL query
Query覆盖了str方法,返回具体的SQL语句
def __str__(self):
"""
Returns the query as a string of SQL with the parameter values
substituted in.
Parameter values won't necessarily be quoted correctly, since that is
done by the database interface at execution time.
"""
sql, params = self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
return sql % params
所以通过
Message.objects.filter(id=121201).query
可以打印出SQL语句。
4.manager定义在django/db/models/manager.py中:
Manager
ManagerDescriptor
EmptyManager
Manager定义了常用的ORM api:
- get_query_set()
- all()
- count()
- distinct()
- get()
- get_or_create()
- create()
- filter()
- aggregate()
- order_by()
- values()
- update()
- reverse()
- exists()
所有这些API都是通过调用get_query_set()委托给querySet实现的。
四、一些疑问和答案
1.django如何查看执行的sql语句?
from django.db import connection
print connection.queries
2.djangor如何拦截到update操作?
from django.db.models import signals
signals.class_prepared.connect(setup_join_cache)
from django.dispatch import Signal
post_update = Signal(providing_args=['instance'])
post_create = Signal(providing_args=['instance'])
3. models对象能直接new吗?
可以:
k = Message()
k.photo_id = 309867
print k.photo
4. 通过filter()执行查询是在什么情况下执行SQL语句的,多次filter()会多次查询吗?
不会,请参考django文档对query_set的解释:
https://docs.djangoproject.com/en/dev/topics/db/queries/
QuerySets are lazy – the act of creating a
QuerySet doesn’t involve any database activity. You can stack filters together all day long, and Django won’t actually run the query until the
QuerySet is
evaluated. Take a look at this example:
>>> q = Entry.objects.filter(headline__startswith="What")
>>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q)
Though this looks like three database hits, in fact it hits the database only once, at the last line (print(q)). In general, the results of a QuerySet aren’t fetched from the database until you “ask” for them. When you do, the QuerySet is evaluated by
参考:
http://blog.xiaket.org/2009/pro-django-ch2-notes-1.html
http://blog.jobbole.com/21351/
http://jeffelmore.org/2010/09/25/smarter-caching-of-django-querysets/