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.

原文地址:https://www.cnblogs.com/SunshineKimi/p/11757524.html

时间: 2024-08-03 05:24:04

jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系的相关文章

SQL数据库中的主键与外键的介绍

一.什么是主键.外键: 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如 : 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯一的,学号就是一个主键 用户表(用户名.密码.登录级别) 其中用户名是唯一的, 用户名就是一个主键 上机记录表(卡号,学号,姓名.序列号) 上机记录表中单一一个属性无法唯一标识一条记录,学号和姓名的组合才可以唯一标识一条记录,所以 学号和姓名的属性组是一个主键 上机记录表中的序列号不是成绩表的

数据库设计中主键问题

转自: http://www.jb51.net/article/40933.htm 数据库主键在数据库中占有重要地位.主键的选取策略决定了系统是否可靠.易用.高效.本文探讨了数据库设计过程当中常见的主键选取策略,并剖析了其做主键的优缺点,提出了相应的解决问题的方法 在基于关系型数据库设计时候,通常要为每张表指定一个主键,所谓主键就是能够唯一标识表中某一行记录的属性或属性组,一个表只能有一个主键,但可以有多个候选索引.因为主键可以唯一标识某一行记录,所以可以确保执行数据更新.删除.修改时不出现错误

mybatis中useGeneratedKeys用法--插入数据库后获取主键值

前言:今天无意在mapper文件中看到useGeneratedKeys这个词,好奇就查了下,发现能解决我之前插入有外键表数据时,这个外键获取繁琐的问题,于是学习敲DEMO记录    在项目中经常需要获取到插入数据的主键来保障后续操作,数据库中主键一般我们使用自增或者uuid()的方式自动生成 问题:对于uuid使用Java代码生成的方式还比较容易控制,然而使用数据库生成的主键,这样我们就需要将插入的数据再查询出来得到主键,某些情况下还可能查询到多条情况,这样就比较尴尬了. 那有什么办法来插入数据

数据库设计中主键字段类型的选择

很久都没有写过博客了,从最后一次发表的文章到现在已经是两个多月的时间了,一直都想写点什么,可一直没有时间(其实都是借口),随笔内容无疑就是工作学习中的总结,经验的分享,也是自己成长的一面镜子,好了,言规正传,这次谈谈在数据库设计中主键字段类型的选择. 做web 开发时,经常要与数据库交互,数据库主键的选择也犹为重要,怎么么选择数据库主键字段的类型,主要从以下几个方面考虑: 1. 首先要符合业务需求,这是设计中重要的出发点 2. 数据库的迁移问题,考虑在后期是否要经常迁移,数据库高度唯一性 3.程

MySQL数据库自增主键归零的几种方法

MySQL自增主键归零的方法: 如果曾经的数据都不需要的话,可以直接清空所有数据,并将自增字段恢复从1开始计数: truncate table table_name; 2.  当用户没有truncate的权限时且曾经的数据不需要时: 1)删除原有主键: ALTER TABLE 'table_name' DROP 'id'; 2)添加新主键: ALTER TABLE 'table_name' ADD 'id' int(11) NOT NULL FIRST; 3)设置新主键: ALTER TABLE

mybatis框架(6)---mybatis插入数据后获取自增主键

mybatis插入数据后获取自增主键 首先理解这就话的意思:就是在往数据库表中插入一条数据的同时,返回该条数据在数据库表中的自增主键值. 有什么用呢,举个例子: 你编辑一条新闻,同时需要给该新闻打上标签(可以一个或者多个:比如:女性,爱,钱等等),然后存储到数据库中.怎么存,肯定涉及到三张表,新闻表,标签表,新闻标签id关联表 新闻表插入数据简单,标签表插入数据简单.那新闻标签表呢,如何关联,那是不是需要新闻表和标签表插入数据的时候,返回它们的主键Id然后再存储到新闻标签表中. 这种场景还是蛮常

mysql 插入数据失败防止自增长主键增长的方法

mysql设置了自增长主键ID,插入失败的那个自增长ID也加一的,比如失败5个,下一个成功的不是在原来最后成功数据加1,而是直接变成加6了,失败次数一次就自动增长1了,能不能让失败的不增长的? 或者说mysql插入数据失败,怎么能防止主键增长? MYSQL不保证AUTO_INCREMENT依次增长(1,2,3,4,5),但是可以保证正向增长(1,3,5,9)所以,当你某次操作失败后,下次AUTO_INCREMENT就不是顺序的了. innodb的自增是缓存在内存字典中的,分配方式是先预留,然后再

Chapter 1. 数据库概述、主键、外键

数据库 database: 存储数据的仓库,用表来分类数据 特点:海量存储:查找速度快:并发性问题的控制:安全性:数据完整性(保存在数据库中的数据是正确的真实的) 数据库软件:DBSM   database management system 常见数据库软件:MySQL  MSSQL server  Oracle  Access SQL:Structured Query Language 结构化查询语言   特点:语言简洁.易学易用. SQL Server:是一种基于网络的大型数据库软件.主要用

mysq数据库设计(主键与外键)

主键可以是真实实体的属性,但是常用的好的解决方案是,利用一个与实体信息不相关的属性,作为唯一标示(加个id字段)主键与业务逻辑不发生关系,只用来标示记录 可以在定义完字段后,再定义多列主键(组合主键) 例:primary key(id,name,age);(不是说3个字段都是主键,因为一个表只能有一个主键,可以是3个字段组合成的主键) 设计: 两个实体表内,存在相同的主键字段 如果记录的主键值等于另一个关系表内记录的主键则两天记录对应 1:1对应  数据库设计的时候(常用的信息和不常用的信息分开