jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系
Posted sunshinekimi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系相关的知识,希望对你有一定的参考价值。
四.models.py 定义和管理模型: 4.1模型class的属性就映射与数据库的字段参数 继承models.Model class TestClass(models.Model): 4.2在数据库生成数据表: #django默认在makemigrations会为表对象创建主键id,id = models.AutoField(primary_key=True) 你也可以自定义一个主键对象: 4.2.1: 生成迁移文件python manage.py makemigrations 4.2.2执行迁移python manage.py migrate show tables; 检查数据库mysql mysql> desc app_grade; +------------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+------------+------+-----+---------+-------+ | grade_id | int(11) | NO | PRI | NULL | | | grade_good | int(11) | NO | | NULL | | | grade_bad | int(11) | NO | | NULL | | | is_delete | tinyint(1) | NO | | NULL | | +------------+------------+------+-----+---------+-------+ 4 rows in set (0.06 sec) mysql> desc app_student; +----------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------------+-------------+------+-----+---------+-------+ | user_name | varchar(20) | NO | | NULL | | | student_id | int(11) | NO | PRI | NULL | | | is_man | tinyint(1) | NO | | NULL | | | createObj_date | datetime(6) | NO | | NULL | | | is_delete | tinyint(1) | NO | | NULL | | | stu_number_id | int(11) | NO | MUL | NULL | | +----------------+-------------+------+-----+---------+-------+ 6 rows in set (0.05 sec) 4.3数据库表关系: class ForeignKey(ForeignObject): """ Provide a many-to-one relation by adding a column to the local model to hold the remote value. By default ForeignKey will target the pk of the remote model but this behavior can be changed by using the ``to_field`` argument. """ # Field flags many_to_many = False # 多对多 --》 学生有多科老师,每科老师有多个学生 many_to_one = True # 多对一 --》学校很穷只有一个老师教多个课程 one_to_many = False # 一对多 one_to_one = False # 一对一 --》 地主家的儿子一对一面对面辅导 外键的删除on_delete可能的值如下:CASCADE,PROTECT,SET_NULL,SET_DEFAULT,SET(),DO_NOTHING CASCADE:这就是默认的选项,级联删除,你无需显性指定它。 PROTECT: 保护模式,如果采用该选项,删除的时候,会抛出ProtectedError错误。 SET_NULL: 置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,允许为空。 SET_DEFAULT: 置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。 SET(): 自定义一个值,该值当然只能是对应的实体了 外键ForeignKey: # For backwards compatibility purposes, we need to *try* and set # the to_field during FK construction. It won‘t be guaranteed to # be correct until contribute_to_class is called. Refs #12190. to_field = to_field or (to._meta.pk and to._meta.pk.name) # https://docs.djangoproject.com/en/1.10/ref/models/fields/ 五.#django中models field详解: 在model中添加字段的格式一般为: field_name = field_type(**field_options) 5.1field options(所有字段共用): null 默认为False,True则表示可以为null。(空字符串在数据库中可能被存储为‘‘) blank 默认为False,True表示可以为空。 choice 可选的,限制了该选项的字段值必须是所指定的choice中的一个。 db_column 数据库column名称。默认为本字段的名称。 db_index 如果为True的话,该字段的数据库索引将会被创建 default 设置该字段的默认值,可以是值也可以是对象。 editable 默认为True,若为False,则不会在admin/界面显示 primary_key 若设置为True,则表示将该字段设置为主键。一般情况下django默认会设置一个自增长的id主键。 unique 若设置为True,该字段值不可重复 5.2 field type(字段类型,细分的话可以分为普通字段以及关系字段): 1.也就是默认pk, AutoField() 根据已有id自增长的整形唯一字段,一般每个model类不需设置该字段,因为django会为每个model自动设置。 django默认会为每个model类添加如下语句:id = models.AutoField(primary_key=True) 当其他字段添加了primary_key属性,则不会创建id字段了 每个model类仅能有一个主键 2.BooleanField() 布尔型字段,默认的表单窗口部件是CheckBoxInput 3.CharField() 字符型字段,默认的表单窗口部件是TextInput。该字段类型有一个必需参数:max_length 在数据库水平限定了字符串最大长度 4. DateField() 日期字段,字段的值是python中datetime.date的实例,默认的表单窗口是TextInput有几个可选的参数: auto_now=True/False:当设置为True时,每当该对象使用save()时,该字段的值就会被更新。 auto_now_add=True/False: 当设置为True时,该字段的值为该对象被创建时的日期 5. DateTimeField() 日期和时间字段,值为datetime.datetime实例。默认的表单窗口以及可选参数同上。 6.DecimalField() 混合精度的小数型数字字段。有两个必需的参数: max_digits=ingt_number:限定数字的最大位数(包含小数位) decimal_places=int_number:存储数字的小数位 #to store numbers up to 999 with a resolution of 2 decimal places, you’d use models.DecimalField(..., max_digits=5, decimal_places=2) 7.EmailField(max_length=254, **options) 邮件字段,使用EmailValidator进行验证 8.FileField(upload_to=None, max_length=100, **options) 文件上传字段。 这个字段不能设置primary_key和unique选项.在数据库中存储类型是varchar,默认最大长度为100. 有两个可选参数: upload_to 如果使用默认的FileSystomStorage(https://docs.djangoproject.com/en/1.10/ref/files/storage/#django.core.files.storage.FileSystemStorage), 文件将会存储到settings文件中配置的MEDIA_ROOT(https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-MEDIA_ROOT)路径中。 upload_to的值也可以为可调用对象,通过调用这个对象可以获得上传路径。 instance=: 定义了FileField的模型实例filename=‘‘: 文件名称 举例: class MyModel01(models.Model): # file will be uploaded to MEDIA_ROOT/uploads upload = models.FileField(upload_to=‘uploads/‘) # or... # file will be saved to MEDIA_ROOT/uploads/2015/01/30 upload = models.FileField(upload_to=‘uploads/%Y/%m/%d/‘) #upload_to=可调用对象 def user_directory_path(instance, filename): # file will be uploaded to MEDIA_ROOT/user_<id>/<filename> return ‘user_{0}/{1}‘.format(instance.user.id, filename) class MyModel02(models.Model): upload = models.FileField(upload_to=user_directory_path) 9.FilePathField(path=None, match=None, recursive=False, max_length=100, **options) 这个字段的值被限制在系统上某个目录中的所有文件名集合中。有三个参数 path=‘‘: 该参数必需。上行所说的‘某个目录’的绝对路径。Example: "/home/images". match=‘pattern‘: 可选参数。格式是正则表达式。用来拣选符合匹配正则表达式的文件 recursive=True/False: 可选参数,默认为False。设定是否递归该目录下所有子目录的所有文件。 FilePathField(path="/home/images", match="foo.*", recursive=True) 10 FloatField() 浮点字段,默认的表单窗口部件是NumberInput。和DecimalField经常混淆不清, FloatField在内部使用Python中的float对象,而DecimalField在内部使用Python中的decimal对象。 11 ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options) 图像字段。继承了FileField的所有属性和方法。而且还能自动验证上传的对象是否为合法的图像。 12 IntegerField 整形字段。 13 GenericIPAddressField(protocol=‘both‘, unpack_ipv4=False, **options) ip地址字段 protocol=‘both/ipv4/ipv6‘ 默认为both unpack_ipv4 用处不大。 14 NullBooleanField 类似于BooleanField,不同的是其允许值为null 15 TextField() 与CharField类似,但一般用来存储体积较大的文本。 16 TimeField(auto_now=False, auto_now_add=False, **options) 时间字段,其值为datetime.time实例 17 URLField(max_length=200, **options) URL字段 类似于CharField的子类,默认最大长度为200. 18 UUIDField(**options) 通用唯一标识字段,当不想用django默认设置的AutoField字段时,可以用该字段代替。 以上18种为普通类型field,接下来介绍关系型field: 1.ForeignKey(othermodel, on_delete, **options) 多对一或者一对多或者外键字段。 othermodel: 所关联的模型,‘多‘ model使用外键关联 ‘一‘model。 当所关联的模型为他自己时,使用‘self‘ 当引用的模型为其他app中的模型时,要加上app名称标签: ‘app_name.model_name‘ 数据库会自动在外键字段上创建索引,可以使用de_index=False关闭该功能。 on_delete: 当删除 "一" 模型对象时,django会根据该参数的值对与该对象相关联的其他对象(也就是 ‘多’)进行操作。 在django1.9以及之前的版本中,on_delete作为一个关键字参数。而在1.10则可以作为第二个参数 models.CASCADE: 默认为models.CASCADE 级联删除。当删除‘一‘时,‘多’会被删除。 比如: # mysite项目下名为polls的app中的models.py class follower(models.Model): name = models.CharField(max_length=200) menpai = models.ForeignKey(‘menpai‘, on_delete=models.CASCADE) #定义了models.CASCADE属性 def __str__(self): return self.name class menpai(models.Model): name = models.CharField(max_length=200) def __str__(self): return self.name #运行 python3 manager.py shell进入交互页面 >>> from polls.models import follower,menpai >>> m1=menpai(name=‘huashanpai‘) >>> m1.save() >>> m2=menpai(name=‘riyuejiao‘) >>> m2.save() >>> f1=follower(name=‘linghuchong‘,menpai=m1) >>> f1.save() >>> f2=follower(name=‘renwoxing‘,menpai=m2) >>> f2.save() >>> f1.menpai <menpai: huashanpai> >>> m1.delete() (2, {‘polls.menpai‘: 1, ‘polls.follower‘: 1}) # 删除华山派时,将令狐冲也删除了 class ForeignKey(ForeignObject): def __init__(self, to, on_delete, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, to_field=None, db_constraint=True, **kwargs): modles.PROTECT : 当删除一个具有外键关系的对象时,会引发一个异常,阻止删除该对象 models.SET_NULL: 设置删除对象所关联的外键字段为null。但字段的null属性必需为True models.SET_DEFAULT : 设置删除对象所关联的外键字段为默认的值。 models.SET(value) :设置删除对象所关联的对象的外键字段为value,value也可以是一个可调用函数。 models.DO_NOTHING : 不做任何操作 related_name 设置从关联对象到自身的关系的名称,若值为‘+‘ 则关联对象与自身无逆向关系,详解请看官方文档(https://docs.djangoproject.com/en/1.10/topics/db/queries/#backwards-related-objects)。 to_field 设置所关联对象的关联字段。默认为关联对象的主键字段。 举例: from django.conf import settings from django.contrib.auth import get_user_model from django.db import models def get_sentinel_user(): return get_user_model().objects.get_or_create(username=‘deleted‘)[0] class MyModel(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user), ) 2.ManyToManyField(othermodel, **options)多对多字段 othermodel: 所关联的model名称 db_table: 多对多关系会在两个模型所对应的表中间创建一个‘中间表’ ,将多对多转换为两个多对一,该选项为这个中间表设置名称。一般来说django会默认为中间表创建名称,但人们读起来可能搞不清楚究竟中间表关联到了哪里。 related_name: 同多对一字段中的related_name limite_choices_to: 同.... symmetrical: 当多对多关联对象为自身时可能会用到的参数。默认为True。a, b同属于person模型,person中的friends字段与自身设置了多对多关系,当该值设置为True时,django假定关系为对称,即:a是b的朋友,那么b也是a的朋友。设置为False时,django会强制为逆向关系创建描述信息。 though: 不想让django自动创建中间表,手动创建中间表所对应的model,通过though指定对应的model名称。 though_field: 当though参数被使用时,该参数才会有效。指定使用哪些中间模型字段来确立两个模型的多对多关系。 OneToOneField(othermodel, on_delete, parent_link=False, **options) 3.一对一字段 othermodel: ....... on_delete: ........ related_name: ........... 六.测试数据操作: 方式一.: 直接在tests.py 执行测试数据TestCase: 方式二: python manage.py shell进入shell: ls 查看目录结构,cls清除cmd 6.1操作对象model与数据库数据 # overide __str__()方法 class Grade(models.Model): grade_id=models.IntegerField(primary_key=True) grade_good=models.IntegerField() grade_bad=models.IntegerField() is_delete=models.BooleanField(default=False) def __str__(self): return "%d,%d" %(self.grade_id,self.grade_good) class A(object): is_man=True is_num=False def __str__(self): # if you want get object return 1,0 from True ,False ,can use "%i %i" %(self.is_man,self.is_num) return "%r %r" %(self.is_man,self.is_num) # 等价于 return "{}{}".format(self.is_man,self.is_num) if __name__ == ‘__main__‘: print(A()) # learn how to operate data of model reflect to db data: for here it you can create an object and get its attr from object or delete the object you create just save for exp: In [18]: from app.models import Grade,Student ...: from django.utils import timezone ...: from datetime import * In [19]: from app.models import Grade,Student gd=Grade() # select one or fetch one row data gd=Grade.objects.get(pk=2) gd.grade_id =122 gd.good_num=999 gd.save() #update the object value by model reflect the db column value #then you can delete object row from model and reflect to db column also : gd.delete() #data insert : grade_new=Grade() grade_new.grade_good=56655 grade_new.save() #select all Grade.objects.all()查所有对象row 6.2关联对象: In [34]: gd=Grade() In [35]: gd.grade_id=1001 In [36]: gd.grade_good=80 In [37]: gd.grade_bad=60 In [38]: gd.save() In [39]: gd Out[39]: <Grade: 1001,80> # query all student objects related with gd object; gd.student_set.all() # related main table with sub_table ,by primary key In [27]: gd01=Grade.objects.get(pk=1) InIn [28]: gd01.student.create(student_id=1002,user_name="张") --------------------------------------------------------------------------- In [41]: gd.student_set.create( user_name="章邯是",student_id=2001) Out[41]: <Student: %s ,%d ,%s> In [42]: gd.delete() Out[42]: (2, {‘app.Student‘: 1, ‘app.Grade‘: 1}) mysql拓展外键与主键: 特点 1) 一个表中只能有一个主键。如果在其他字段上建立主键,则原来的主键就会取消。在ACCESS中,虽然主键不是必需的,但最好为每个表都设置一个主键。 2)主键的值不可重复,也不可为空(NULL)。 外键: 如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的联系。 以另一个关系的外键作主键main table的表被称为主表,具有此外键的表被称为主表的sub table从表。外键又称作外关键字。 以上是摘抄的,简单来说,主键就是一个关系中作为标识用的,而外键是其他关系中的属性,使用外键可避免冗余。 主键、外键和索引的区别? 主键,外键,索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 该字段没有重复值,但可以有一个空值 作用: 用来保证数据完整性 用来和其他表建立联系用的 是提高查询排序的速度 个数: 主键只能有一个 一个表可以有多个外键 一个表可以有多个惟一索引 七.admin管理应用之站点管理: 7.1 settings.py : INSTALLED_APPS = [ ‘django.contrib.admin‘, #添加django.contrib.admin ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, "app" ]
1.
以上是关于jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系的主要内容,如果未能解决你的问题,请参考以下文章
19 01 15 django 数据库设计模型 管理站点 注意:在引入外键在django 2以上改版
jango下一对一对应查询,django列类型,分页,CSR攻击
使用 django-import-export 在 django 迁移中的外键