1,模型定义

models.py的例子:

 class Author(models.Model):
name=models.CharField(max_length=20) class Book(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=50)
author=models.ForeignKey(Author)
length=models.IntegerField()

主键的唯一性:如果没有设置主键,django会设置一个自增id,其类型为django的AutoField(一个自增的整数)。

当然,你可以在变量的属性中添加primary_key=True让其成为主键,这意味着这个变量的值必须是唯一的。还有一个类似的属性unique=True,这也能保证变量的唯一性,不过你不需要将它作为主键。

2.模型之间的关系

外键

 class Author(models.Model):
name=models.CharField(max_length=20) class Book(models.Model):
name=models.CharField(max_length=50)
author=models.ForeignKey(Author)

需注意,一定要先把被引用的类放前面,否则Author变量名是不会被Book类中的ForeignKey识别的,当然也可以通过字符来替代,这样就不必担心顺序先后的问题,如下:

 class Book(models.Model):
name=models.CharField(max_length=50)
author=models.ForeignKey("Author") class Author(models.Model):
name=models.CharField(max_length=20)

ForeignKey只定义了关系的一端,不过另一端却能根据关系找到,外键从关系上将是“多对一”关系,多个子对象引用一个父对象。如下例子:

 #models.py
class Book(models.Model):
title=models.CharField(max_length=50)
author=models.ForeignKey("Author")
#author=models.ForeignKey("Author",related_name="books") class Author(models.Model):
name=models.CharField(max_length=20) #views.py
def test(request):
book=Book.objects.get(title="Moby dic")
author=book.author
books=author.book_set.all()
#books=author.books.all()

从上面可以看到Author到Book的反向关系是通过Author.book_set表示的。

上面的例子中,我们可以再Foreignkey里指定的related_name参数改变它的名字,如果我们把author定义成ForeignKey("Author",related_name="books")的话,最后就访问author.books,而不是author.book_set了。

多对多关系

外键通常只能表示一对一或多对一关系,如上我们只能表示一本书只能有一位作者。但是如果一本书有多个作者的情况如何表示呢?这时就需要多对多关系了,dango为这种情况提供了ManyToManyField。你再关系的一段定义它,把要关联的类传递进来,ORM会自动在另一端生成使用这个关系必要的方法和属性(和ForeignKey一样,通常生成一个_set manager对象)。

我们将上面的一对多关系改成多对多关系,如下:

 class Book(models.Model):
title=models.CharField(max_length=50)
authors=models.ManyToManyField("Author") class Author(models.Model):
name=models.CharField(max_length=20)

我们查看数据库后多一张表:

 mysql> show tables like 'blog%';
+------------------------+
| Tables_in_mydb (blog%) |
+------------------------+
| blog_author |
| blog_book |
| blog_book_authors |
+------------------------+
4 rows in set 1 mysql> desc blog_book;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int() | NO | PRI | NULL | auto_increment |
| title | varchar() | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
rows in set mysql> desc blog_author;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int() | NO | PRI | NULL | auto_increment |
| name | varchar() | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
rows in set mysql> desc blog_book_authors;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int() | NO | PRI | NULL | auto_increment |
| book_id | int() | NO | MUL | NULL | |
| author_id | int() | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
rows in set 

我们可以从sql中查出新建的表blog_book_authors中的字段实际上是两个外键,如下:

 mysql> show create table blog_book_authors;
+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| blog_book_authors | CREATE TABLE `blog_book_authors` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`book_id` int(11) NOT NULL,
`author_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `blog_book_authors_book_id_author_id_0a5bb3b3_uniq` (`book_id`,`author_id`),
KEY `blog_book_authors_book_id_35eae5ed` (`book_id`),
KEY `blog_book_authors_author_id_fa034e3d` (`author_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set

通过如下代码查询:

     book=Book.objects.title(title="python developement")
authors=book.authors_set.all()
books=authors[2].book_set.all()

上面的代码和下面是一样的,通过through你可以手工管理中间类上的额外变量,同时还能方便的管理关系两端:

 class Author(models.Model):
name=models.CharField(max_length=20) class Book(models.Model):
title=models.CharField(max_length=50)
# author=models.ForeignKey("Author")
authors=models.ManyToManyField("Author",through="Authoring") class Authoring(models.Model)
coll_type=models.CharField(max_length=100)
book=models.ForeignKey("Book")
author=models.ForeignKey("Author")

继承模型

抽象基础类和多表继承

抽象基础类:

是纯python的继承,这样变量和方法从基类继承下来,子类在数据库的表还是复制了基类的变量。

 class Author(models.Model):
name=models.CharField(max_length=20) class Book(models.Model):
title=models.CharField(max_length=100)
genre=models.CharField(max_length=40)
num_pages=models.IntegerField()
authors=models.ManyToManyField("Author") def __unicode__(self):
return self.title class Meta: #只作为一个抽象类,只能被继承,不能被实例化
abstract=True class SmithBook(Book):
authors=models.ManyToManyField(Author,limit_choices_to={'name__endswith':'Smith'})

SmithBook的定义和下面是一样的:

 class  SmithBook(Book):
title=models.CharField(max_length=100)
genre=models.CharField(max_length=40)
num_pages=models.IntegerField()
authors=models.ManyToManyField(Author,limit_choices_to={'name__endswith':'Smith'}
      def __unicode__(self):
return self.title

如果基类用到了related_name参数来设置ForeignKey这样的变量的话,需要用一些字符串格式化来避免子类的名字发生冲突,不要使用related_employess之类的常见字符串,而应该用%(class)s,这样“related_%(class)s“,子类的名字就能被正确替换,避免发生冲突。

多表继承

最新文章

  1. mvc DropDownList默认选项
  2. 自然语言18.2_NLTK命名实体识别
  3. C#,.Net自动生成大写字母编码
  4. 基于Qt的流程设计器(一)
  5. http://www.zhihu.com/question/24896283
  6. CMake编译linux C++
  7. java新手笔记34 连接数据库
  8. KXFW界面库
  9. chrome下老是弹出网页显示 true
  10. 条件变量signal与unlock的顺序
  11. hdu-5794 A Simple Chess(容斥+lucas+dp)
  12. [原创]嵌入CEF遇到的问题及解决方案
  13. C++11 单例类实现
  14. [daily][archlinux][game] 几个linux下还不错的游戏
  15. HDOJ 1023 Train Problem II
  16. vue动画
  17. 基础的shell脚本
  18. node.js、git、bootstrap等安装配置
  19. 100W数据,测试复合索引
  20. 【腾讯敏捷转型NO.1】敏捷是什么鬼?

热门文章

  1. Java中程序、进程、线程的区别。
  2. JLINK固件烧写
  3. IPC——管道
  4. ACM-ICPC 2018 徐州赛区网络预赛 G. Trace (思维,贪心)
  5. AtCoder Beginner Contest 133 F Colorful Tree
  6. 接口自动化平台搭建(四),自动化项目Jenkins持续集成
  7. waitpid()
  8. asp.net中gridview控件的一些基本使用方法
  9. Linux如何杀掉tty终端
  10. c#调用