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,它和列表很像,但有所不同,包括[:]等方法都是改造后的,比起列表会更节约内存。

posted on 2010-09-17 21:09  真阿当  阅读(121)  评论(0编辑  收藏  举报