写一个地道的django model

做web开发,编码往往以建模开始,下面以django1.5为标准,扯扯写一个地道的django model.(django1.4绝大部分可以兼容)


1.首先要对Field Options有个基本的认识(属性是面向model类而言的,字段是面向数据库而言的)

    model由属性field组成,不同field类型,有不同的options,先了解所有field都公共的options。官网有比较多的options,选取常规开发能用到的几个说一说。

    null选项, 表示数据库层面的检验,能否为null,默认为False,就是说数据库里这个属性对应的字段默认不能存储null

    blank选项,能否为空值empty value(不是None空对象),None存到数据库就是null,这个选项与数据库无关,是一个纯django层面的检验,比如form的校验,能否允许empty value就取决于这个选项

    choices选项,指定这个属性的值只能是哪几种可能,具体写法看文档https://docs.djangoproject.com/en/1.5/ref/models/fields/#django.db.models.Field.choices

    db_column选项,指定数据库表里这个属性对应字段的名字,默认是属性名字,无特殊需要,不用理会。如果实际需要更改,比如使用一个已经存在的数据库,确保名字可用

    db_index选项,是否为这个属性对应字段添加索引,即使有这个需要,unique可以胜任

    default,不用说了,赋默认值

    editable,是否可编辑,默认true,如果不可编辑,将不会再model-form和admin中的添加修改出现

    error_messages,该属性用户输入不符合要求时,提示信息,默认已有,除非不满足你的要求,不用理会。

  help_text,帮助信息,当用户输入填写表单时,提示用户这个该怎么输入

  verbose_name,官网有个解释很好A human-readable name for the field。简略的说:属性名cat,verbose_name=U"猫",那么页面上就显示猫,不是cat


2.写好每一个属性

  1.数值字符串类型:大整数使用 BigIntegerField

              一般IntegerField

              确定值很小 可以节约空间使用 SmallIntegerField

    浮点数,高精度浮点,字符串,布尔,IP,邮箱,URL,等等分别使用其对应类型即可,另外有些带Positive修饰,检验正负,总之一句话:请使用最精确的类型。

    此外CommaSeparatedIntegerField不是整数,别被名字骗了,本质还是字符串

    大量文本使用TextField,个人觉得百K是上限,再大过M就不适合了

    更大,那就自定义类型,指向底层数据库支持的大数据类型,这个比较简单。

  2.日期时间类型:DateField,TimeField,DateTimeField

    如果你要记录首次添加时间,auto_now_add=True

    如果你要记录最后更新时间,auto_now=True,这两个就不要自己动脑筋实现了

    但是注意QuerySet批量更新时,不是依次调用每个对象的更新函数,不会触发auto_now,批量更新其他字段时记得连带更新最后时间

 3.上传文件,使用FileField相关文档太长,简要概括

    upload_to指定上传目录,storage如何管理你上传的文件,默认就够用。有几个可选,看看差异即可。

    但是,models类读取文件属性和普通属性有所区别:

    读取文件属性返回值是一个FieldFile对象,代表你上传的文件,这个对象的url属性表示文件路径,open,close,delete,save方法用于操作文件。

    此外FilePathField与文件基本无关,也别被名字骗了,本质是个字符串,只不过要求这个字符串表示的文件路径正确有效,有些选项可以控制文件或目录,不详述。

    ImageField是FileField子类,只不过加了几个与图片相关的控制参数,用法一样

  4.外键,比如

    1.class Comment(models.Model):
         target = models.ForeignKey(XXX)#XXX另一个model 类,表示对XXX的一个评论

      如果外键要指向自己,比如要表示对评论的评论,使用self,或者自己的类名parent =models.ForeignKey('self')或者models.ForeignKey('Comment')

      parent就表示上一级评论,使用字符串表示类名,在程序运行时,这个类名必须能在ContentType找到,简单点说,就是存在并且被django加载了。不了解django的ContentType没关系,不需要用django内置的一些玩意就用不着。

   2.related_name,指定反向查找时的key,举例:

      上例中xxx.comment_set.all()可以取出该XXX的所有评论,是因为默认related_name就是类名Comment的全小写comment+"_set",默认就够使用了

       什么时候必须指定呢?上面的model添加两个属性

      from_user =models.ForeignKey(User, related_name='from_me')

      to_user =models.ForeignKey(User, related_name='to_me')

       此时如不指定related_name就会报错,因为django不知道该如何反向取值了。如果按照上面分别指定了related_name,那么外键反向取值,如下

      user.from_me.all()就能取出我发出的所有评论

      user.to_me.all()取出所有发给我的评论

    3.limit_choices_to 没啥说的,限制外键取值范围

    4.to_field,是指外键指向另一个表(模型)的哪一个字段(属性),默认指向主键id.可以修改指向别的字段(属性),不过确保其唯一性

     5.on_delete是说外键指向的对象删除时,本对象应该采取的措施,默认级联删除。

        一共有cascade, protect, set_null, set_default, set(), do_nothing等选择,详见https://docs.djangoproject.com/en/1.5/ref/models/fields/#django.db.models.ForeignKey.on_delete



   5.多对多

      跟外键差不多,只说不同的。

           1. symmetrical,对称性。比如User有个多对多键friends指向User,我添加你做朋友,自动地,你也是我的朋友,这就是对称性,默认为true,开启。

            可以设置False,关闭后,我添加你做朋友,我的好友列表有你。你的好友列表没有我。

          2.through,过渡表。django默认的多对多实现是采用中间过渡表完成。比如A多对多B,那么有张中间表

                 id:中间表自己的主键

                a_id:指向A表主键

                b_id指向B表主键

            用这张过渡表记录AB的多对多关系。很遗憾,这张表就只有三个字段,不能记录其他信息,比如我是什么时间添加你做朋友。想要存储额外信息到过渡表,就该 使用through了。官网有个例子https://docs.djangoproject.com/en/1.5/topics/db/models/#intermediary-manytomany

           3.db_table,过渡表表名。如上文,AB多对多过渡表表名默认为a_b,二者类名下划线链接,再小写。你可以指定其他名字。


     6.一对一,跟外键几乎一样,多一个选项(options),叫parent_link,没啥大作用。给个地址看看官网解释https://docs.djangoproject.com/en/1.5/ref/models/fields/#django.db.models.OneToOneField.parent_link


3.最后一点了,Meta设置

       abstract 用来指定是否是抽象类,抽象类不会生成表,适合用于面向对象的基类

    app_label默认不用指定,django自省即可(别问什么是自省啊,有百度可以问)。当你的model定义在models.py或者models包外时,或者是动态模型,那就必须指定了,值就是你的app名字即可。关于动态模型,详见django dynamic models and field injections

    db_table默认值是“appName”+“_”+ “modelName”,可以指定别的表名。使用已存在的库表时有用。

    get_latest_by,指定django的latest函数取最新记录时默认按什么排序

    ordering指定模型默认按什么排序,注意此设置会反映到数据库层面,并且会有外键传递影响

    permissions指定该模型需要额外创建的权限代码,默认add  change  delete 三种

       unique_together  指定数据库表中哪几列必须组合起来唯一,不能全部相同。同联合主键。

        index_together  指定数据库表中哪几列必须组合起来建立索引。与unique_together唯一区别在于不要求组合唯一。

       verbose_name给你的模型取一个好理解的好阅读的名字在页面上显示,

    verbose_name_plural是verbose_name的复数,默认verbose_name+“s“

     

    proxy order_with_respect_to不常用,managed一般不需改变,有需要可看看文档

 

充分利用django内置的实现完成你的功能,不要自己苦思冥想去实现一些偏僻的功能,而且尽最大可能写最精确的代码,就OK了。









    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值