Python Web框架篇:Django Model基础

model是关于你的数据的单一的,肯定的信息来源。 它包含您正在存储的数据的基本字段和行为。Django经过抽象化的模型层(models)为你的网络应用提供对于数据的结构化处理和操做处理,数据库相关的代码通常写在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,使用数据库API对数据库进行增删改查的操做。python

使用哪一种数据库,只须要在settings.py中配置便可,如:mysql

<1> sqlite: django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3 git

<2> mysql:引擎名称:django.db.backends.mysqlsql

<3>若是想更改数据库:shell

 1 DATABASES = {  2     'default': {  3         'ENGINE': 'django.db.backends.mysql',  4         'NAME': 'books',    #你的数据库名称
 5         'USER': 'root',   #你的数据库用户名
 6         'PASSWORD': '', #你的数据库密码
 7         'HOST': '', #你的数据库主机,留空默认为localhost
 8         'PORT': '3306', #你的数据库端口
 9  } 10 
11 }
View Code

注意事项:数据库

1 NAME即数据库的名字,在mysql链接前该数据库必须已经建立,而上面的sqlite数据库下的db.sqlite3则是项目自动建立 2 USER和PASSWORD分别是数据库的用户名和密码。 3 设置完后,再启动咱们的Django项目前,咱们须要激活咱们的mysql。 4 而后,启动项目,会报错:no module named MySQLdb 5 这是由于django默认你导入的驱动是MySQLdb,但是MySQLdb对于py3有很大问题,因此咱们须要的驱动是PyMySQL 6 
7 因此,咱们只须要找到项目名文件下的__init__,在里面写入: 8 import pymysql 9 pymysql.install_as_MySQLdb()
View Code

Model 字段django

 1 AutoField 根据实际ID自动增加的IntegerField . 你一般不须要直接使用;  2  若是不指定,一个主键字段将自动添加到你建立的  3 BigIntegerField 一个64位整数, 相似于一个 IntegerField 这个字段默认的表单组件是一个TextInput.  4 
 5 IntegerField([**options])  6 一个整数。在Django所支持的全部数据库中,从 -2147483648 到 2147483647 范围内的值是合法的。默认的表单输入工具是TextInput.  7 
 8 BinaryField 用来存储原始二进制码的Field. 只支持bytes 赋值,注意这个Field只有颇有限的功能。  9  例如,不大可能在一个BinaryField 值的数据上进行查询 10 BooleanField    true/false 字段。默认表单挂件是一个CheckboxInput. 11  若是你须要设置null 值,则使用NullBooleanField 来代替BooleanField。 12  若是Field.default没有指定的话, BooleanField 的默认值是 None。 13 CharField 一个用来存储从小到很大各类长度的字符串的地方。 14  若是是巨大的文本类型, 能够用 TextField. 15  这个字段默认的表单样式是 TextInput. 16  CharField必须接收一个额外的参数: 17  CharField.max_length¶:字段的最大字符长度.max_length将在数据库层和Django表单验证中起做用, 用来限定字段的长度. 18 DateField 这是一个使用Python的datetime.date实例表示的日期. 有几个额外的设置参数: 19 
20  DateField.auto_now¶ 每次保存对象时,自动设置该字段为当前时间。 21                 用于"最后一次修改"的时间戳。注意,它老是使用当前日期;它不仅是一个默认值,你能够覆盖。 22 
23  DateField.auto_now_add¶ 当对象第一次被建立时自动设置当前时间。用于建立时间的时间戳. 24  它老是使用当前日期;和你能够覆盖的那种默认值不同。 25 
26  该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件, 27                 和一个“Today"的快捷按钮.包含了一个额外的invalid_date错误消息键.
28 
29 
30     DateTimeField(DateField)    - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 31 
32     DateField(DateTimeCheckMixin, Field)    - 日期格式      YYYY-MM-DD 33 
34     TimeField(DateTimeCheckMixin, Field) - 时间格式 HH:MM[:ss[.uuuuuu]] 35 
36 DurationField(Field)用做存储一段时间的字段类型 - 相似Python中的timedelta. 37             - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 38 
39 DecimalField(max_digits=None, decimal_places=None[, **options]) 表示十进制浮点数 40  
41 EmailField([max_length=254, **options])一个 CharField 用来检查输入的email地址是否合法。它使用 EmailValidator 来验证输入合法性。 42 
43 FileField([upload_to=None, max_length=100)一个上传文件的字段。 44 FileField字段不支持primary_key 和unique参数,若是使用会生成 TypeError错误 45 
46 FilePathField(path=None[, match=None, recursive=False, max_length=100]) 47 一个 CharField ,内容只限于文件系统内特定目录下的文件名。有三个参数, 其中第一个是 必需的: 48 
49 FloatField([**options])用Python的一个float 实例来表示一个浮点数. 50 
51 
52 ImageField([upload_to=None, height_field=None, width_field=None, max_length=100, **options])¶ 53 继承了 FileField的全部属性和方法, 但还对上传的对象进行校验,确保它是个有效的image. 54 
55 TextField([**options])大文本字段。该模型默认的表单组件是Textarea。 56 
57 TimeField([auto_now=False, auto_now_add=False, **options])¶ 58 时间字段,和Python中 datetime.time 同样。接受与DateField相同的自动填充选项。 59 表单默认为 TextInput.输入框。 60 
61 URLField([max_length=200, **options])一个CharField 类型的URL此字段的默认表单widget为TextInput。 62 
63 UUIDField([**options])一个用来存储UUID的字段。使用Python的UUID类。 64 当使用PostgreSQL数据库时,该字段类型对应的数据库中的数据类型是uuid
View Code

字段选项(Field options)——参数

 1 Field.null 若是为True,Django将在数据库中将空值存储为NULL。默认值是 False。
 2 
 3 Field.blank 若是为True,则该字段容许为空白。 默认值是 False。
 4 
 5 Field.choices 它是一个可迭代的结构(好比,列表或是元组),
 6 由可迭代的二元组组成(好比[(A, B), (A, B) ...]),用来给这个字段提供选择项。
 7 若是设置了 choices ,默认表格样式就会显示选择框,而不是标准的文本框,并且这个选择框的选项就是 choices 中的元组。
 8 
 9 Field.db_column 数据库中用来表示该字段的名称。若是未指定,那么Django将会使用Field名做为字段名.
10 
11 Field.db_index 若值为 True, 则 django-admin sqlindexes 将会为此字段输出 CREATE INDEX 语句。
12 
13 
14 Field.error_messages 可以让你重写默认抛出的错误信息。经过指定 key 来确认你要重写的错误信息。
15 
16 Field.primary_key若为 True, 则该字段会成为模型的主键字段。
17 若是你没有在模型的任何字段上指定 primary_key=True, Django会自动添加一个 AutoField 字段来充当主键。
18 
19 Field.unique 若是为 True, 这个字段在表中必须有惟一值.
20 
21 Field.unique_for_month 相似unique_for_date,只是要求字段对于月份是惟一的。
22 
23 验证器
24 Field.validators 该字段将要运行的一个Validator 的列表。
View Code

元信息Meta——使用内部的class Meta 定义模型的元数据后端

from django.db import models
class Ox(models.Model):
horn_length = models.IntegerField()
class Meta:
ordering = ["horn_length"]
verbose_name_plural = "oxen"

模型元数据是任何不是字段的数据,好比排序选项(ordering),数据表名(db_table)或者人类可读的单复数名称(verbose_name verbose_name_plural)。网络

在模型中添加class Meta是彻底可选的,全部选项都不是必须的。
app

关系字段

关系数据库的威力体如今表之间的相互关联。

Django 提供了三种最多见的数据库关系:多对一(manyto-one),多对多(many-to-many),一对一(one-to-one)
多对一关系
Django 使用 django.db.models.ForeignKey 定义多对一关系。和使用其它字段类型同样:在模型当中把它作为一个类属性包含进来。
ForeignKey 须要一个位置参数:与该模型关联的类。

 1 limit_choices_to 当这个字段使用模型表单或者Admin 渲染时(默认状况下,查询集中的全部对象均可以使用),
 2 为这个字段设置一个可用的选项。它能够是一个字典、一个Q 对象或者一个返回字典或Q对象的可调用对象。
 3         Q(caption='root')
 4         db_constraint=True          # 是否在数据库中建立外键约束
 5         parent_link=False           # 在Admin中是否显示关联数据
 6 
 7 related_name    这个名称用于让关联的对象反查到源对象。它仍是related_query_name 的默认值(关联的模型进行反向过滤时使用的名称)。
 8 
 9 related_query_name    这个名称用于目标模型的反向过滤。若是设置了related_name,则默认为它的值,不然默认值为模型的名称
10 
11 to_field 关联到的关联对象的字段名称。默认地,Django 使用关联对象的主键。
12 
13 db_constraint控制是否在数据库中为这个外键建立约束。默认值为True
14 
15 on_delete 当一个ForeignKey 引用的对象被删除时,Django 默认模拟SQL 的ON DELETE CASCADE 的约束行为,而且删除包含该ForeignKey的对象。这种行为能够经过设置on_delete 参数来改变。
16 
17     CASCADE级联删除;默认值。
18 
19     PROTECT抛出ProtectedError 以阻止被引用对象的删除,它是django.db.IntegrityError 的一个子类。
20 
21     SET_NULL把ForeignKey 设置为null; null 参数为True 时才能够这样作。
22 
23     SET_DEFAULT ForeignKey值设置成它的默认值;此时必须设置ForeignKey 的default 参数。
24 
25     SET() 设置ForeignKey 为传递给SET() 的值,若是传递的是一个可调用对象,则为调用后的结果。
26     DO_NOTHING不采起任何动做。若是你的数据库后端强制引用完整性,它将引起一个IntegrityError ,除非你手动添加一个ON DELETE 约束给数据库自动
View Code

ManyToManyField一个多对多关联。

要求一个关键字参数:与该模型关联的类,与ForeignKey 的工做方式彻底同样,包括递归关系 和惰性关系。
关联的对象能够经过字段的RelatedManager 添加、删除和建立。

 1 若是源模型和目标不一样,则生成如下字段:
 2 id:关系的主键。
 3 <containing_model>_id:声明ManyToManyField 字段的模型的id。
 4 <other_model>_id:ManyToManyField 字段指向的模型的id。
 5 
 6 若是ManyToManyField 的源模型和目标模型相同,则生成如下字段:
 7 id:关系的主键。
 8 from_<model>_id:源模型实例的id。
 9 to_<model>_id:目标模型实例的id。
10 这个类可让一个给定的模型像普通的模型那样查询与之相关联的记录。
11 
12     to,                         # 要进行关联的表名
13     related_name=None,          # 反向操做时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
14     related_query_name=None,    # 反向操做时,使用的链接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
15     
16     limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
17         # 如:
18             - limit_choices_to={'nid__gt': 5}
19             - limit_choices_to=lambda : {'nid__gt': 5}
20 
21             from django.db.models import Q
22             - limit_choices_to=Q(nid__gt=10)
23             - limit_choices_to=Q(nid=8) | Q(nid__gt=10)
24             - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
25        
26    symmetrical=None,# 仅用于多对多自关联时,symmetrical用于指定内部是否建立反向操做的字段
27                 # 作以下操做时,不一样的symmetrical会有不一样的可选字段
28                     models.BB.objects.filter(...)
29 
30                     # 可选字段有:code, id, m1
31                         class BB(models.Model):
32 
33                         code = models.CharField(max_length=12)
34                         m1 = models.ManyToManyField('self',symmetrical=True)
35 
36                     # 可选字段有: bb, code, id, m1
37                         class BB(models.Model):
38 
39                         code = models.CharField(max_length=12)
40                         m1 = models.ManyToManyField('self',symmetrical=False)
41 
42         through=None,               # 自定义第三张表时,使用字段用于指定关系表
43         through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段作多对多关系表
44             from django.db import models
45 
46             class Person(models.Model):
47                 name = models.CharField(max_length=50)
48 
49             class Group(models.Model):
50                 name = models.CharField(max_length=128)
51                 members = models.ManyToManyField(
52                     Person,
53                     through='Membership',
54                     through_fields=('group', 'person'),
55                 )
56 
57             class Membership(models.Model):
58                 group = models.ForeignKey(Group, on_delete=models.CASCADE)
59                 person = models.ForeignKey(Person, on_delete=models.CASCADE)
60                 inviter = models.ForeignKey(
61                     Person,
62                     on_delete=models.CASCADE,
63                     related_name="membership_invites",
64                 )
65                 invite_reason = models.CharField(max_length=64)
66                 
67         db_constraint=True,         # 是否在数据库中建立外键约束
68         db_table=None,              # 默认建立第三张表时,数据库中表的名称
View Code

OneToOneField

一对一关联关系。概念上讲,这个字段很像是ForeignKey 设置了unique=True,不一样的是它会直接返回关系另外一边的单个对象。

它最主要的用途是做为扩展自另一个模型的主键;例如,多表继承就是经过对子模型添加一个隐式的一对一关联关系到父模型实现的。

须要一个位置参数:与该模型关联的类。 它的工做方式与ForeignKey 彻底一致,包括全部与递归关系和惰性关系相关的选项。

 


 如下内容我的理解笔记:

        class News(models.Model):
            title = models.CharField(max_length=10)
            favor = models.ManyToManyField('User',through="Favor",through_fields=("new_obj", 'user_obj'))
# obj = models.News.objects.get(id=1)
# v = obj.favor.all()
# print(v)
# obj.favor.add(1)不能用
# obj.favor.remove(1)不能用
# v = obj.favor.all()能用
# obj.favor.clear()能用,根据id删,不用name这个字段
# v = models.User.objects.all()
# v = models.User.objects.all().select_related('user_type')class User(models.Model):
 name = models.CharField(max_length=10) email = models.EmailField(max_length=10) user_type = models.ForeignKey('UserType') # 一对多 # user_profile = models.ForeignKey('UserDetail',unique=True) user_profile = models.OneToOneField('UserDetail') class UserDetail(models.Model): pwd = models.CharField(max_length=32) class Favor(models.Model): new_obj = models.ForeignKey('News',related_name="n") user_obj = models.ForeignKey('User',related_name='u') name = models.CharField(max_length=64,null=True,blank=True) class UserType(models.Model): name = models.CharField(max_length=10)

访问外键(Foreign Key)值
python manage.py shell

当你获取一个ForeignKey 字段时,你会获得相关的数据模型对象。
>>> from django.db import connection
>>> from app01.models import User
>>> u=User.objects.get(id=1)
>>> u
<User: User object>
>>> u.user_type
<UserType: UserType object>
>>> u.user_type.name
'type1'


对于用ForeignKey 来定义的关系来讲,在关系的另外一端也能反向的追溯回来,
经过一个UserType对象,直接获取 user ,用 UserType.user_set.all() ,
实际上,user_set 只是一个 QuerySet(参考第5章的介绍),
因此它能够像QuerySet同样,能实现数据过滤和分切,属性名称user_set是由模型名称的小写加_set组成的。
>>> from app01.models import UserType
>>> t=UserType.objects.get(name='type1')
>>> t.user_set.all()
<QuerySet [<User: User object>, <User: User object>]>

 


多对多
正向查找
>>> from app01.models import News
>>> n=News.objects.get(id=1)
>>> n.favor.all()
<QuerySet [<User: User object>, <User: User object>]>

>>> n.favor.filter(name='nu1')
<QuerySet [<User: User object>]>

反向查找>>> u.news_set.all()<QuerySet [<News: News object>]>

相关文章
相关标签/搜索