django db models探索

一、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定义了很多常用的查询接口:

  1. iterator
  2. aggregate
  3. count
  4. get
  5. create
  6. get_or_create
  7. latest
  8. delete
  9. update
  10. exists
  11. values
  12.  filter
  13. exclude
  14. 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: 所有这些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/

猜你喜欢

转载自san-yun.iteye.com/blog/1835682