`
san_yun
  • 浏览: 2655004 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

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:
  1. get_query_set()
  2. all()
  3. count()
  4. distinct()
  5. get()
  6. get_or_create()
  7. create()
  8. filter()
  9. aggregate()
  10. order_by()
  11. values()
  12. update()
  13. reverse()
  14. 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/

分享到:
评论

相关推荐

    PyPI 官网下载 | django-models-redis-cache-1.0.9.tar.gz

    《PyPI上的Django Models Redis Cache 1.0.9:高效数据库缓存策略解析》 在Python的Web开发领域,Django框架以其强大的功能和灵活性深受开发者喜爱。而为了进一步提升性能,开发者通常会利用缓存技术来优化数据访问...

    Django对models里的objects的使用详解

    这个`objects`属性继承自`django.db.models.Manager`类,能够调用一系列内置的数据库操作方法,如`all()`, `get()`, `filter()`, `create()`等。这些方法可以帮助我们快速实现数据的增删改查操作,并返回一个`...

    Django数据库内省工具通过数据表名就可以动态创建一个即时可用的Djangomodels对象

    from django.db.models.base import ModelBase from django.db.models.fields import * ``` 接着,我们可以使用`connections`来获取数据库连接,然后调用`introspection`模块中的方法来获取表的信息: ```python ...

    Django更新models数据库结构步骤

    ### Django更新Models数据库结构步骤详解 #### 一、引言 在使用Django进行Web开发的过程中,经常会遇到需要更新或调整已有模型的情况。这可能是因为业务需求的变化导致我们需要添加、修改或删除某些字段。然而,在...

    django简易版网盘

    2. **文件上传**:在Django中,文件上传主要通过`django.core.files`和`django.db.models.FileField`实现。开发者需要定义模型字段来存储文件,并创建视图处理文件上传请求,确保安全性和稳定性。 3. **文件下载**...

    django_models

    Django模型类通常是基于Python的普通类,它们继承自`django.db.models.Model`基类。例如: ```python from django.db import models class Book(models.Model): title = models.CharField(max_length=200) ...

    Django官方文档中文翻译(models部分)

    from django.db import models class User(models.Model): username = models.CharField(max_length=20) password = models.CharField(max_length=40) ``` 2. 字段类型:Django模型支持多种字段类型,如...

    models_django管理_django_django的一个model_

    from django.db import models class User(models.Model): username = models.CharField(max_length=30, unique=True) password = models.CharField(max_length=128) # 假设我们使用哈希密码 email = models....

    django数据模型on_delete, db_constraint的使用详解

    总结来说,理解并正确使用 `on_delete` 和 `db_constraint` 参数对于构建健壮且灵活的Django应用至关重要。它们允许你在数据模型层面上定义删除行为和关系约束,以适应不同场景的需求,同时保持数据的一致性和完整性...

    Python+Django 官网例子

    模型是Python类,继承自django.db.models.Model。 ```python from django.db import models class User(models.Model): name = models.CharField(max_length=100) email = models.EmailField() ``` 5. **数据库...

    详解Django的model查询操作与查询性能优化

    在Django的shell中,可以通过导入django.db.connection来查看查询情况。当我们执行一个查询语句时,比如使用Books.objects.all()获取所有书籍信息,可以使用connection.queries来查看底层生成的SQL语句及执行时间。...

    Django查询数据库的性能优化示例代码

    前言 Django数据层提供各种途径优化数据的访问,一个项目大量优化工作一般是放在... from django.db import models class Job(models.Model): title=models.CharField(max_length=32) class UserInfo(models.Model)

    django-polls案例

    from django.db import models class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): question ...

    django框架模型层功能、组成与用法分析

    本文实例讲述了django框架模型层功能、组成与用法。...from django.db import models class ModelName(models.Model): field1 = models.xxfield(..) field2 = models.xxfield(..) ... class Meta: db_table = .

    django-db-views:为Views模型创建自动迁移,像在正常makemigrations中一样,使用反向和完整命令选项

    django-db-views 如何安装? pip install django-db-views 如何使用? 将django_db_views添加到INSTALLED_APPS 使用makeviewmigrations命令为视图模型创建迁移 如何在数据库中创建视图? 要使用DBView类创建视图...

    Mysql数据库反向生成Django里面的models指令方式

    在Django框架中,当你已经有一个预先存在的MySQL数据库,并且想要将其模型化为Django的models.py文件时,可以使用内置的`inspectdb`管理命令。这个命令可以帮助你快速生成基于现有数据库表的模型类。标题提到的...

    单独提取django_orm

    模型类是Python类,继承自django.db.models.Model,包含了字段(Field)定义,如CharField、IntegerField等,这些字段对应数据库表的列。模型类还可以定义方法,实现对数据的业务逻辑处理。 二、模型与数据库表的...

    Django基础.rar

    from django.db import models class User(models.Model): username = models.CharField(max_length=50) email = models.EmailField() password = models.CharField(max_length=100) def __str__(self): ...

    Django(三)模型与数据库

    首先,Django模型是Python类,它们继承自`django.db.models.Model`基类。模型中的每个类属性都代表数据库表中的一个字段。例如,假设我们有一个`User`模型,可以这样定义: ```python from django.db import models...

Global site tag (gtag.js) - Google Analytics