Django补充

1.Django ORM def __unicode__
类似 _str__ 方法,多为python2情况下使用


2.
models.Manager:自定义manager以定制数据库访问,默认manager会有get_query_set()方法,
它返回为默认的查询 objects 即 models.objects.all() 可以重写此方法达到查询指定数据的作用

from django.db import models

**# First, define the Manager subclass.**
**class DahlBookManager(models.Manager):**
**def get_query_set(self):**
**return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')**

**# Then hook it into the Book model explicitly.**
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
# ...

**objects = models.Manager() # The default manager.**
**dahl_objects = DahlBookManager() # The Dahl-specific manager.**

在这个示例模型中,Book.objects.all()返回了数据库中的所有书本,而Book.dahl_objects.all()只返回了一本.
注意我们明确地将objects设置成manager的实例,因为如果我们不这么做,那么唯一可用的manager就将是dah1_objects

3.
class meta:
abstract 是否抽象类(是否生成):
这个属性是定义当前的模型类是不是一个抽象类。所谓抽象类是不会对应数据库表的。一般我们用它来归纳一些公共属性字段,
然后继承它的子类可以继承这些字段。比如下面的代码中Human是一个抽象类,Employee是一个继承了Human的子类,
那么在运行syncdb命令时,不会生成Human表,但是会生成一个Employee表,它包含了Human中继承来的字段,以后如果再添加一个Customer模型类,
它可以同样继承Human的公共属性:


4.
自定义方法:models中可以使用各种自定义的方法,执行对数据的对应操作:

为了给你的对像添加一个行级功能,那就定义一个自定义方法。 有鉴于manager经常被用来用一些整表操作(table-wide),模型方法应该只对特殊模型实例起作用。
这是一项在模型的一个地方集中业务逻辑的技术。
最好用例子来解释一下。 这个模型有一些自定义方法:
from django.contrib.localflavor.us.models import USStateField
from django.db import models

class Person(models.Model):
  first_name = models.CharField(max_length=50)
  last_name = models.CharField(max_length=50)
  birth_date = models.DateField()
  address = models.CharField(max_length=100)
  city = models.CharField(max_length=50)
  state = USStateField() # Yes, this is U.S.-centric...

  def baby_boomer_status(self):
    "Returns the person's baby-boomer status."
    import datetime
    if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
      return "Baby boomer"
    if self.birth_date < datetime.date(1945, 8, 1):
      return "Pre-boomer"
    return "Post-boomer"

  def is_midwestern(self):
    "Returns True if this person is from the Midwest."
    return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')

  def _get_full_name(self):
    "Returns the person's full name."
    return u'%s %s' % (self.first_name, self.last_name)
  full_name = property(_get_full_name)

例子中的最后一个方法是一个property。 想了解更多关于属性的信息请访问http://www.python.org/download/releases/2.2/descrintro/#property
这是用法的实例:
>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.birth_date
datetime.date(1961, 8, 4)
>>> p.baby_boomer_status()
'Baby boomer'
>>> p.is_midwestern()
True
>>> p.full_name # Note this isn't a method -- it's treated as an attribute
u'Barack Obama'
View Code


5.
settings中:(多数据库使用)
DATABASE_ROUTERS = ['cpapi.router.DefaultRouter',] 可以设置多个数据库连接,优先级从左到右
db_for_read(model, **hints)
建议 model 对象写操作时使用的数据库。

如果一个数据库操作可以提供对选择数据库有用的附加信息,那么可以通过 hints 字典提供。详见 下文 。

如果没有建议则返回 None 。

db_for_write(model, **hints)
建议 model 对象读操作时使用的数据库。

如果一个数据库操作可以提供对选择数据库有用的附加信息,那么可以通过 hints 字典提供。详见 下文 。

如果没有建议则返回 None 。

allow_relation(obj1, obj2, **hints)
当 obj1 和 obj2 之间允许有关系时返回 True ,不允许时返回 False ,或者没有 意见时返回 None 。这是一个纯粹的验证操作,用于外键和多对多操作中,两个对象 的关系是否被允许。

allow_syncdb(db, model)
决定 model 是否可以和 db 为别名的数据库同步。如果可以返回 True , 如果不可以返回 False ,或者没有意见时返回 None 。这个方法用于决定一个给定 数据库的模型是否可用。
一个路由不必提供 所有 这些方法,可以省略其中一个或多个。如果其中一个方法被 省略了,那么 Django 会在执行相关检查时跳过相应路由。


6.
实现自定义的manage命令:
django-admin.py调用django.core.management来执行命令:
#!/usr/bin/env python
from django.core import management

if __name__ == "__main__":
management.execute_from_command_line()

excute_from_command_line()函数会根据命令行参数解析出命令的名称,根据命令名称调用相应的Command执行命令。Command位于各个管理模块的commands模块下面。

所谓管理模块,是指在app模块下的名字为management的模块。Django通过django.core.management.find_management_module函数发现"管理模块":

然后通过django.core.management.find_commands函数找到命令类。find_commands函数会在管理模块下查找.py文件,并将.py文件的名称匹配到命令名称:
最后,通过django.core.management.load_command_class函数加载该.py文件中的Command类:

在执行命令的时候,会执行相应Command类的handle方法。所有的Command类都应该是django.core.management.base.BaseCommand的直接或间接子类。

原理搞清楚了,扩展manage命令就很容易了。创建一个app并加入到settings的INSTALLED_APPS中,在该app下面创建management.commands模块,并创建hello.py文件:
from django.core.management.base import BaseCommand, CommandError
from django.db import models
#from placeholders import *
import os

class Command(BaseCommand):
def handle(self, *args, **options):
print 'hello, django!'
复制代码
就可以使用hello命令了:

$ python manage.py hello
hello, django!

posted @ 2017-11-07 20:59  Mitsuis  阅读(171)  评论(0编辑  收藏  举报