一、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 clone3. 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: 所有这些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/