Django module
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“,子类的名字就能被正确替换,避免发生冲突。
多表继承
Django module的更多相关文章
- Django ~module index
https://docs.djangoproject.com/en/1.9/py-modindex/ django.conf.urls django.contrib.admin django.db.m ...
- virtualenv中ImportError: No module named django
问题现象:在代码py文件中,import django 报错,但是在python shell中直接执行这个语句没错, 网上搜索了下,自己测试了下,确定原因是由于使用了python中的virtualen ...
- Nginx+uWSGI+Django+Python在Linux上的部署
搞了一整天,终于以发现自己访问网络的端口是错误的结束了. 首先要安装Nginx,uWSGI,Django,Python,这些都可以再网上查到. 安装好后可以用 whereis 命令查看是否安装好了各种 ...
- Awesome Django
Awesome Django If you find Awesome Django useful, please consider donating to help maintain it. ...
- Django线上部署教程:腾讯云+Ubuntu+Django+Uwsgi(转载)
网站名称: 向东的笔记本 本文链接: https://www.eastnotes.com/post/29 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议.转载请注明出处! ...
- 01:CENTOS使用VIRTUALENV搭建独立的PYTHON环境-PYTHON虚拟环境
1.1 安装virtualenv环境 https://www.cnblogs.com/liuyansheng/p/6141197.html 1.安装virtualenv yum install pyt ...
- Graphite简要教程
转载自DevOps实战:Graphite监控上手指南 英文原文Getting Started with Monitoring using Graphite 英文原文Google快照 作者 Frankl ...
- 安装Django时报错'module' object has no attribute 'lru_cache'
使用pip方法安装Django时报错'module' object has no attribute 'lru_cache' 解决办法如下 命令行输入命令sudo pip install Django ...
- Error loading MySQLdb module: No module named 'MySQLdb'----------- django成功连接mysql数据库的方法
在进行django学习过程中,尝试使用框架连接mysql数据库,启动服务器的时候经常遇到Error loading MySQLdb module: No module named 'MySQLdb' ...
随机推荐
- pkg-config命令
返回已安装库文件的元信息 pkg-config读取.pc文件获取信息 基本思想 编译的时候-I指定头文件路径:-L指定库文件路径.这样做总感觉很麻烦 事先把库的位置信息等保存起来,需要的时候再通过特定 ...
- zabbix low-level discovery 监控mysql
当一台服务器上MySQL有多个实例的时候,MySQL占用多个不同端口.利用zabbix的low-level discovery可以轻松监控. 思路参考:http://dl528888.blog.51c ...
- I2C总线、设备、驱动
I2C总线.设备.驱动 框架 I2C驱动框架可分为3个部分,分别是:I2C核心层.I2C总线驱动层(适配器层)以及I2C设备驱动层: I2C核心层 提供了统一的I2C操作函数,主要有两套函数smbus ...
- Java 中的多态,一次讲个够之继承关系中的多态
多态是继封装.继承之后,面向对象的第三大特性. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一个 ...
- less避免编译
less里面有一个避免编译,有时候我们需要输出一些不正确的css语法或者使用less不认识的专有语法.要输出这样的值我们可以在字符串前加上一个~ /*避免编译*/ .test_03{ width: 3 ...
- Vant UI 组件库如何做rem适配?
Vant是一款移动端基于vue的组件库,V2.1.1版本非常棒.文档地址:https://youzan.github.io/vant/?source=vuejsorg#/zh-CN/intro,那么V ...
- ZZNU-OJ-2118 -(台球桌面碰来碰去,求总距离)——模拟到爆炸【超时】的不能AC的代码
ZZNU-2118 : 早安晚安,不如我先入土为安 题目描述 spring比较喜欢玩台球,因为看着台球在桌子上碰来碰去很有意思(台球撞壁反弹,入射角等于反射角),每次完美的台球入洞,都能体现他数学天才 ...
- JavaScript中的变量提升和严格模式
1.什么是变量提升 所谓的变量提升指的是:函数声明和变量声明总是会被解释器悄悄地被"提升"到方法体(作用域)的最顶部. //先声明后使用 var x; console.log(x) ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 【 题目:so easy】{并查集维护一个数的下一个没有被删掉的数} 补题ING
题意:给[1,n],n个数,有两种操作: 1 x,删去x2 x,查询还未被删去的数中大于等于x的最小的数是多少. input: output: 做法:按照并查集的方法压缩路径 代码: #include ...
- Ubuntu: error: snap “phpstorm” has “install-snap” change in progress
Ubuntu: error: snap “phpstorm” has “install-snap” change in progress 投稿日 : 2019-06-10 | カテゴリー : linu ...