• django学习笔记(四)


    1)关于模型类属性的类型,和数据库中的类型有对应关系,但事实上django扩展了一些新的类型。这些类型最终还是会被转化成数据库支持的类型,但这些新类型会自动获得一些验证的作用(提交表单时,会进行正则匹配)。

    CharField和TextField都是保存文本,但CharField是定长的,而TextField的长度则可以是无限的。EmailField、URLField和IPAddressField这三个变量其实就是在CharField加上一点额外的验证。BooleanField和NullBooleanField的区别是后者允许为空。FileField是最复杂的变量之一,它只在数据库是保存了一个文件的路径。

    2)模型之间的关系。ForeignKey()可以传模型类进去,也可以传字符串进去,如果传模型类进去,那么模型必须在被传之前先定义,如果传模型进去,那么模型定义的顺序就没有要求了。

    class Author(models.Model):

    >> name = models.CharField(max_length=100)

    class Book(models.Model):

    >> title = models.CharField(max_length=100)

    >> author = models.ForeignKey(Author)                          #=>   Author必须在前面先定义

    =================================================================

    class Book(models.Model):

    >> title = models.CharField(max_length=100)

    >> author = models.ForeignKey(‘Author’)                          #=>   Author不必在前面先定义

    class Author(models.Model):

    >> name = models.CharField(max_length=100)

    3)虽然ForeignKey只定义了关系的一端,不过另一端却能根据关系追溯回来(和rails两边都要写has_one不同)。外键从技术上说是一个“多对一”的关系,即可以有多个子对象引用同一个父对象。因此子对象只有一个父对象的引用,而父对象却能访问到一组子对象。

    book = Book.objects.get(title="Myby Dick")

    author = book.author

    books = author.book_set.all()

    可以看到从Author到Book的“反向关系”是通过Author.book_set属性来表示的,你可以通过在ForeignKey里指定related_name参数来改变它的名字。在上面的例子里,我们如果把author定义成ForeignKey("Author",related_name="books")的话,最后就是访问author.books而不是author.book_set了。

    对于简单的对象层次来说,related_name不是必需的,但是在更复杂的关系里,比如当你有多个ForeignKey的时候就一定要指定了。这时,ORM需要你明确告诉它在ForeignKey的另一端如何区分两个不同的反向关系。如果你忘了的话,Django的数据库管理工具会抛出错误信息警告你!

    4)处理多对多关系可以用ManyToManyField,它的用法和外键关系里的“多”的那一端差不多:

    book = Book.objects.get(title="Python")

    authors = book.author_set.all()

    books = authors[2].book_set.all()

    5)一对一可以用OneToOneField。

    6)ForeignKey和ManytoManyField都可以指定一个limit_choices_to参数,它是个字典类型,用以限制关系。

    class Author(models.Model):

    >> name = models.CharField(max_length=100)

    class SmithBook(models.Model):

    >> title = models.CharField(max_length=100)

    >> authors = models.ManyToManyField(Author,limit_choices_to={'name_endswith':'Smith'})

    7)django的模型对应的是数据库中的表,而模型其实是类,可以被继承的。在django中模型继承有两种方式,一种称为抽象继承,另一种称为多表继承。抽象继承是让基类成为抽象类,不会对应数据库中的表,而多表继承就是普通的python类继承,基类并非抽象类,也会对应于数据库中的表。抽象类是如何实现的呢?是依靠在Meta嵌套类中设置abstract=True实现的。

    class Author(models.Model):

    >> name = models.CharField(max_length=100)

    class Book(models.Model):

    >> title = models.CharField(max_length=100)

    >> genre = models.CharField(max_length=100)

    >> num_pages = models.IntegerField()

    >> authors = models.ManyToManyField(Author)

    >> class Meta:

    >>>> abstract = True

    class SmithBook(Book):

    >> authors = models.ManyToManyField(Author,limit_choices_to={'name_endswith':'Smith'})

    给Book的Meta嵌套类设置了abstract=True,所以在创建数据库的时候,只会有Author和SmithBook两张表。如果去掉abstract,那么即为多表继承,包括Book在内,会创建三张表。

    8)django用manage.py syncdb来同步数据库,但它只关心“有无数据库表”,不关心“是否修改了数据库表”,如果没有,那么创建。如果已经有了,就不再关心。所以如果对模型进行修改了,再运行syncdb,不会同步我们的修改的。需要手动修改数据库,或者干脆删除表甚至数据库,重新创建。

    9)模型类的常用查询方法有如下这些:

    1》all() 返回所有

    2》filter() 返回满足条件的所有(复数形式)

    3》exclude() 和filter()正相反,不满足条件的所有

    4》get() 获取单个符合条件的记录(没找到或有超过一个结果都会抛出异常)

    5》order_by() 排序

    6》distinct() 去重

    10)给filter()等方法传参,除了name="adang"之类的,还可以用下划线连接一些特殊字符来拼成特定的sql语句。例如name__contains="adang"、age_gt=25,此外还有icontains(大小写无关的LIKE),startswith、endswith、in等。

    11)查询返回的数据类型为QuerySet,它和列表很像,但有所不同,包括[:]等方法都是改造后的,比起列表会更节约内存。

  • 相关阅读:
    技术的极限(8): 集成与分离
    心智与认知(1): 反馈循环(Feedback loop)
    证明与计算(6): 身份认证与授权
    证明与计算(5): 从加密哈希函数到一致性哈希
    技术的极限(6): 密码朋克精神(Cypherpunk Spirit)
    翻译(3): NULL-计算机科学上最糟糕的失误
    工具(5): 极简开发文档编写(How-to)
    证明与计算(3): 二分决策图(Binary Decision Diagram, BDD)
    证明与计算(2): 离散对数问题(Discrete logarithm Problem, DLP)
    翻译(2): How to Write a 21st Century Proof
  • 原文地址:https://www.cnblogs.com/cly84920/p/4426679.html
Copyright © 2020-2023  润新知