添加或修改数据模型不可马虎,对数据的操作需要慎重考虑。推荐Django数据模型相关包:django-model-utils:使用其TimeStampedModeldjango-extensions:使用其管理命令shell_plus,会自动加载所有已安装应用的数据模型库Splitapplicationswithmanydatamodels推荐有每个应用程序不超过5个数据模型。如果一个应用的数据模型太多,就意味着这个应用做了太多的事情,需要拆分。谨慎选择数据模型继承方式Django支持三种继承方式:抽象基类多表继承代理模型Django抽象基类和Python抽象基类是不一样的!,它们具有不同的目的和行为。各种继承方式的优缺点:继承方式的优缺点抽象基类:只有继承的子数据模型才会创建数据表可以在抽象父类中定义公共项,减少重复输入,没有额外的数据表多表继承和join操作的开销父类不能单独使用多表继承:父类和子类都会创建对应的数据表。两者之间存在隐含的OneToOneField关联。由于每个数据模型都有一个表,因此可以对父子进行查询操作。同时可以通过parent.child直接从父对象访问子对象。对子表的查询将与其所有父表进行连接操作。强烈反对多表继承!代理模型:只为原始数据模型创建数据表可以为原始数据模型创建别名,添加不同的Python行为不能修改数据模型项如何确定应该使用哪种继承方式:如果重叠如果数量很小(只有一个或两个项目),您不需要使用继承,只需在两个数据模型中定义它即可。如果两者之间有很多重复项,则应该重构代码,将相同的项放在抽象基类中的代理模型中有时会有用,但它与其他两种模型继承方式和多表继承有很大不同应该避免,因为它会增加复杂性和性能开销。可以改用OneToOneField和ForeignKeys。数据模型继承实践:TimeStampedModel在数据模型中添加创建和修改两个时间戳项是一个常见的需求。你可以写一个TimeStampedModel基类如下:``fields."""created=models.DateTimeField(auto_now_add=True)modified=models.DateTimeField(auto_now=True)classMeta:abstract=True那么所有从这个抽象基类继承的数据模型都会有这两项:#flavors/models.pyfromdjango.dbimportmodelsfromcore.modelsimportTimeStampedModelclassFlavor(TimeStampedModel):title=models.CharField(max_length=200)数据库迁移Django内置了一个强大的数据库修改传导库,叫做migrations,即django。数据库迁移。创建迁移的建议:创建新应用程序或数据模型后,为新数据模型创建初始django.db.migrations。其实我们只需要使用pythonmanage.pymakemigrations命令在运行之前检查生成的迁移代码即可,尤其是涉及复杂修改的时候。同时使用sqlmigrate命令查看实际使用的SQL语句。使用MIGRATION_MODULES配置项来管理第三方应用程序的迁移。不要担心生成的迁移。我们可以使用squashmigrations命令来合并、部署和管理迁移:在部署之前,您应该检查迁移是否可以回滚。如果表中有数百万行,则应在具有该数量级数据的登台服务器上进行测试。在真实数据库上的迁移可能比预期花费更多的时间!如果使用MySQL:必须在涉及任何模式修改之前进行备份。MySQL不为模式修改提供事务支持,因此无法回滚。如果可能,应在执行修改之前将项目置于只读模式。涉及大量表的模式修改可能会花费很多时间。不是秒,不是分钟,而是小时!Django数据模型设计规范数据库一个数据模型不应该包含已经存储在其他数据模型中的数据。相关资源:http://en.wikipedia.org/wiki/Database_normalizationhttp://en.wikibooks.org/wiki/Relational_Database_Design/Normalization缓存应该在非规范化之前完成仅在绝对必要时才进行非规范化何时使用Null和Blank数据项typesetnull=Truesetblank=TrueCharField、TextField、SlugField、EmailField、CommaSeparatedIntegerField、UUIDField不要这样设置。Django的传统是将null值存储为空字符串,可以设置获取NULL或者空值解析为空字符串。如果允许其对应的表单项接受空值。FileField、ImageField不要这样设置。Django只是将MEDIA_ROOT到文件的路径保存在CharField中,所以规则可以这样设置,但是CharFieldBooleanField等规则不应该这样设置。不要使用这个Field,使用NullBoolField,不要设置IntegerField,FloatField,DecimalField,DurationField等,如果允许NULL存入数据库,可以这样设置如果允许其对应的表单组件接受空值,可以这样设置,同时设置null=TrueDateFieldField、DateField、TimeField等,如果允许NULL存入数据库,可以这样设置。如果允许其对应的表单组件接受空值,或者使用auto_now、auto_now_add,可以这样设置。同时需要设置null=TrueForeignKey,ManyToManyField,OneToOneField,可以这样设置,可以这样设置,可以这样设置,可以这样设置,可以这样设置这个,你可以这样设置Django1.8中添加的,用于存储原始二进制数据,或字节。无法对此类项目执行过滤、排除或其他SQL操作。但它在以下情况下很有用:内容传感器原始数据MessagePack格式的压缩数据。例如,Sentry将数据保存为BLOB,但由于历史原因,需要进行base64编码的二进制数据字符串可能非常大,这会降低数据库的速度。此时内容应保存在文件中,然后用FileField引用。永远不要通过BinaryField提供文件服务:读取和写入数据库比文件系统慢。你的数据库会越来越大,导致性能越来越低。这时候访问文件需要经过两层:Django应用层和数据库层。层。尽量避免使用通用关联models.field.GenericForeignKey。使用GenericForeignKey将使外键不受完整性约束。存在以下问题:由于模型之间缺少索引,会降低查询速度。数据表可能引用了一条不存在的记录,存在数据损坏的风险。优点是数据项可以与不同类型的记录相关联,因为没有完整性约束。主要用于投票、标记、评级。可以使用ForeignKey和ManyToMany来实现GenericForeignKey的功能,这样既保证了数据的完整性,又提高了性能。因此,尽量避免使用泛型关联和GenericForeignKey。如果需要泛型关联,尝试看看是否可以通过调整数据模型设计或使用新的PostgreSQL项来解决。如果必须,最好使用现成的第三方应用程序PostgreSQL专用项:何时使用Null和Blank数据项类型放。如果要在数据库中存储NULL,则可以设置。如果允许其对应的表单组件接受空值。还设置null=TrueDatatimeRangeField和DateRangeField数据模型API_meta的同上_meta仅在Django1.8之前在内部使用。该接口已公开开箱即用。_meta的用途:获取数据模型中的项列表获取数据模型中特定项的类(或继承链或其他派生信息),以确保您获取这些信息的方式在未来的Django版本中不会改变.示例:为Django数据模型创建一个内省工具创建一个自定义表单库创建一个类似管理的工具来编辑或与Django数据模型中的数据交互创建一个可视化或分析库,例如分析以开头的项目的信息数据"foo"模型管理器数据模型管理器用于限制一个数据模型类所有可能的数据记录。Django为每个数据模型类提供了一个默认管理器。我们可以自己定义数据模型管理器,比如:fromdjango.dbimportmodelsfromdjango.utilsimporttimezoneclassPublishedManager(models.Manager):use_for_related_fields=Truedefpublished(self,**kwargs):returnself.filter(pub_date__lte=timezone.now(),**kwargs)classFlavorReview(models.Model):review=models.CharField(max_length=255)pub_date=models.DateTimeField()#添加我们的自定义模型管理器objects=PublishedManager()此时,如果我们想先找出所有评论的数量,然后再找出发表评论的数量,可以这样做:>>>fromreviews.modelsimportFlavorReview>>>FlavorReview.objects.count()35>>>FlavorReview.objects。published().count()31更换数据模型的默认管理器要特别小心:首先,在使用数据模型继承时,抽象基类的子类接收其父类的数据模型管理器,但使用多表继承的子类没有。其次,应用于数据模型类的第一个数据模型管理器将用作默认管理器。这与普通的Python模式非常不同,并且会返回与预期不同的查询结果。因此,objects=models.Manager()应该放在所有自定义数据模型管理器之前。理解fatmodels的概念fatmodels是:不把数据相关的代码分散在视图和模板中,而是把这些逻辑封装在数据模型方法、类方法、属性,甚至管理器方法中。这样,所有视图和任务都可以重用这段代码。这种方式的缺点:数据模型的代码量会增加,难以维护和理解。因此,当数据模型中的代码量变得庞大复杂时,应该将相关重复的代码分离出来,放在ModelBehavior或HelperFunctions中。数据模型的行为,也称为Mixins数据模型的行为通过使用Mixins追求组合和封装的概念。相关资源:使用even来减少代码重复无状态辅助函数将此逻辑放在辅助函数集中,使其保持分离并使测试更容易。缺点是:因为这些函数是无状态的,所以需要传递所有的参数。参考:两勺Django:Django1.8最佳实践
