[Django1.5]two-scoops-django-best-practices 笔记三

来源:互联网 发布:dedecms 帝国 cms 编辑:程序博客网 时间:2024/05/16 06:28

chapter 6 



数据库/模型 最佳实践:
模型是很多Django项目的基础。
这是我们挑选的用于模型的第三方包
*South 用来做数据库迁移,这是一个很好用很常见的工具
*django-model-utils  to handle common patterns like  TimeStampedModel
*django-extensions 它有一个强有里的shell工具来自动装载所有app的模型


基本知识:
*拆分有太多模型的app
如果一个app中有超过20个模型,那么就要把它拆分成小的app了,可能这一个app做的东西太多了。实际操作中,一般每个app的模型不超过5个


*不是必要的情况,不要使用原生的sql
如果可以使用ORM来配置数据库操作,请优先使用。
使用原生SQL使得app的可移植性降低
Django BDFL Jacob  Kaplan-Moss  says (paraphrased): If it's easier to write  a query using 
SQL  than  Django,  then  do  it.  extra()  is  nasty  and  should  be  avoided;  raw()  is  great and should be used where appropriate


*在需要的时候增加indexs 
我们的习惯是开始不添加index,需要的时候才添加
我们考虑增加index的情况:
*index使用非常频繁,百分之10~25的查询中都需要它
*我们可以通过测试来衡量生成的indexs是否提高了查询性能
*有真实的数据或者接近真实的数据,我们可以使用index来分析


*小心模型继承
Django提供了3中模型继承的方式:abstract base classes,multi-table inberitance ,proxy models
注意:Django Abstract Base Classes!= Python Abstract Base Classes 
 避免 Multi-Table 继承


模型继承的案例:The TimeStampedModel 时间戳模型
# Code taken with permission from Carl Meyer's # very useful django-model-utilsfrom django.db import modelsfrom django.utils.timezone import nowfrom django.utils.translation import ugettext_lazy as _class AutoCreatedField(models.DateTimeField):    """    A DateTimeField that automatically populates itself at    object creation.    By default, sets editable=False, default=now    """    def __init__(self, *args, **kwargs):        kwargs.setdefault('editable', False)       kwargs.setdefault('default', now)            super(AutoCreatedField, self).__init__(*args, **kwargs)class AutoLastModifiedField(AutoCreatedField):    """    A DateTimeField that updates itself on each save() of     the model.    By default, sets editable=False and default=now.    """    def pre_save(self, model_instance, add):        value = now()        setattr(model_instance, self.attname, value)        return valueclass TimeStampedModel(models.Model):    """    An abstract base class model that provides self-    updating ``created`` and ``modified`` fields.    """    created = AutoCreatedField(_('created'))    modified = AutoLastModifiedField(_('modified'))    class Meta:        abstract = True  #声明为抽象基类 
测试:
# flavors/models.pyfrom django.db import modelsfrom model_utils import TimeStampedModelclass Flavor(TimeStampedModel):    title = models.CharField(max_length=200)
Django的模型设计:
*从标准化开始,一定要熟悉,datebase normalization
*在没标准化之前缓存
*只有特殊需求下才可以不遵守标准


什么时候使用null 和 blank
在设置一个字段的属性的时候有 null=True and blank=True的选项,默认都是False的
具体建议请参照书中表格:ex 文本型字段 使用blank=True


模型控制器:Model Managers 
可以自己定制 小案例:
from django.db import modelsfrom django.utils import timezoneclass PublishedManager(models.Manager):    def published(self, *args, **kwargs):        qs = self.get_query_set().filter(*args, **kwargs)        return qs.filter(pub_date__lte=timezone.now())class FlavorReview(models.Model):    review = models.CharField(max_length=255)    pub_date = models.DateTimeField()        # add our custom model manager    objects = PublishedManager()
注意:1 在模型继承中,抽象基类的自定义模型控制器会遗传给孩子,实体类不会
 2 不同的model class中使用时要特别小心