django5 表关系,字段,创建关系表,添加与查询
模型层普通字段,表关系字段
(1)普通字段
字段表
| 
 字段名  | 
 参数  | 
 意义  | 
| 
 AutoField  | 
 
  | 
 一个能够根据可用ID自增的 IntegerField  | 
| 
 BooleanField  | 
 
  | 
 一个真/假(true/false)字段  | 
| 
 CharField  | 
 (max_length)  | 
 一个字符串字段,适用于中小长度的字符串。对于长段的文字,请使用 TextField  | 
| 
 CommaSeparatedIntegerField  | 
 (max_length)  | 
 一个用逗号分隔开的整数字段  | 
| 
 DateField  | 
 ([auto_now], [auto_now_add])  | 
 日期字段  | 
| 
 DateTimeField  | 
 ([auto_now], [auto_now_add])  | 
 时间日期字段,接受跟 DateField 一样的额外选项  | 
| 
 EmailField  | 
 
  | 
 一个能检查值是否是有效的电子邮件地址的 CharField  | 
| 
 FileField  | 
 (upload_to)  | 
 一个文件上传字段  | 
| 
 FilePathField  | 
 (path,[match],[recursive])  | 
 一个拥有若干可选项的字段,选项被限定为文件系统中某个目录下的文件名  | 
| 
 FloatField  | 
 (max_digits,decimal_places)  | 
 一个浮点数,对应Python中的 float 实例  | 
| 
 ImageField  | 
 (upload_to, [height_field] ,[width_field])  | 
 像 FileField 一样,只不过要验证上传的对象是一个有效的图片。  | 
| 
 IntegerField  | 
 
  | 
 一个整数。  | 
| 
 IPAddressField  | 
 
  | 
 一个IP地址,以字符串格式表示(例如: "24.124.1.30" )。  | 
| 
 NullBooleanField  | 
 
  | 
 就像一个 BooleanField ,但它支持 None /Null 。  | 
| 
 PositiveIntegerField  | 
 
  | 
 和 IntegerField 类似,但必须是正值。  | 
| 
 PositiveSmallIntegerField  | 
 
  | 
 与 PositiveIntegerField 类似,但只允许小于一定值的值,最大值取决于数据库.  | 
| 
 SlugField  | 
 
  | 
 嵌条 就是一段内容的简短标签,这段内容只能包含字母、数字、下 划线或连字符。通常用于URL中  | 
| 
 SmallIntegerField  | 
 
  | 
 和 IntegerField 类似,但是只允许在一个数据库相关的范围内的数值(通常是-32,768到 +32,767)  | 
| 
 TextField  | 
 
  | 
 一个不限长度的文字字段  | 
| 
 TimeField  | 
 ([auto_now], [auto_now_add])  | 
 时分秒的时间显示。它接受的可指定参数与 DateField 和 DateTimeField 相同。  | 
| 
 URLField  | 
 
  | 
 用来存储URL的字段。  | 
| 
 XMLField  | 
 (schema_path)  | 
 它就是一个 TextField ,只不过要检查值是匹配指定schema的合法XML。  | 
字段通用参数表
| 
 参数名  | 
 意义  | 
| 
 null  | 
 如果设置为 True 的话,Django将在数据库中存储空值为 NULL 。默认为 False 。  | 
| 
 blank  | 
 如果是 True ,该字段允许留空,默认为 False 。  | 
| 
 choices  | 
 一个包含双元素元组的可迭代的对象,用于给字段提供选项。  | 
| 
 db_column  | 
 当前字段在数据库中对应的列的名字。  | 
| 
 db_index  | 
 如果为 True ,Django会在创建表格(比如运行 manage.py syncdb )时对这一列创建数据库索引。  | 
| 
 default  | 
 字段的默认值  | 
| 
 editable  | 
 如果为 False ,这个字段在管理界面或表单里将不能编辑。默认为 True 。  | 
| 
 help_text  | 
 在管理界面表单对象里显示在字段下面的额外帮助文本。  | 
| 
 primary_key  | 
 如果为 True ,这个字段就会成为模型的主键。  | 
| 
 radio_admin  | 
 默认地,对于 ForeignKey 或者拥有 choices 设置的字段,Django管理界面会使用列表选择框(<select>)。如果 radio_admin 设置为 True 的话,Django就会使用单选按钮界面。  | 
| 
 unique  | 
 如果是 True ,这个字段的值在整个表中必须是唯一的。  | 
| 
 unique_for_date  | 
 把它的值设成一个 DataField 或者 DateTimeField 的字段的名称,可以确保字段在这个日期内不会出现重复值。  | 
| 
 unique_for_month  | 
 和 unique_for_date 类似,只是要求字段在指定字段的月份内唯一。  | 
| 
 unique_for_year  | 
 和 unique_for_date 及 unique_for_month 类似,只是时间范围变成了一年。  | 
| 
 verbose_name  | 
 除 ForeignKey 、 ManyToManyField 和 OneToOneField 之外的字段都接受一个详细名称作为第一个位置参数。  | 
(2)表关系字段
ForeignKey、ManyToManyField、oneTooneField的对应关系

例子:
学生表应有一个学院表ForeignKey
学生详情表应有一个学生表oneTooneField
课程表应有一个学生表ManyToManyField

表关系字段的参数
- 第一个参数都是别的模型的模型名
 - 外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错!
 
一般使用CASCADE表示级联删除,关于on_delete还有其他的一些属性:
- 
- on_delete=models.CASCADE==>主表属性删除,相关联的子表属性会一并删除 (推荐)
 - on_delete=models.SET_NULL, null=True ==>主表属性删除,相关联的字表属性会变成NULL
 - on_delete=models.PROTECT==>有关联的时候,不允许删除,否则会报错
 
 
表创建
(1)模型定义
创建学院表:
class Department(models.Model):
    d_id = models.AutoField(primary_key=True)
    d_name = models.CharField(max_length=10)
    def __str__(self):
        return 'Department<d_id=%s, d_name=%s>'%(
            self.d_id, self.d_name
        )
创建学生表,与学院表成一对多,外键关联:
class Student(models.Model):
    s_id = models.AutoField(primary_key=True)
    s_name = models.CharField(max_length=10)
    department = models.ForeignKey('Department', on_delete=models.CASCADE)
def __str__(self):
        return 'Student<s_id=%s, s_name=%s>'%(
            self.s_id, self.s_name
        )
学生详情表,与学生表一对一
class Stu_Detail(models.Model):
    s_id = models.OneToOneField('Student', on_delete=models.CASCADE)
    age = models.IntegerField()
    gender = models.BooleanField(default=True)
    city = models.CharField(max_length=30)
    def __str__(self):
        return 'Stu_Detail<s_id=%s, age=%s, gender=%s, city=%s>'%(
            self.s_id, self.age, self.gender, self.city
        )
课程表,与学生表成多对多,自动生成三方表
class Course(models.Model):
    c_id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=10)
    student = models.ManyToManyField('Student')
def __str__(self):
        return 'Course<c_id=%s, name=%s>'%(
            self.c_id, self.name
        )
(2)迁移
settings
#sqllite3
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
#mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'djangostudent',  # 数据库名字
        'USER': 'root',  # 账号
        'PASSWORD': 'root',  # 密码
        'HOST': 'localhost',  # IP
        'PORT': '3306',  # 端口
    }
}
执行makemigrations和migrate
python manage.py makemigrations#生成init文件
python manage.py migrate#迁移
添加数据
通过创建管理员对象和数据库操作可以进行数据添加的基本操作
在学生表和学院表之间进行关联对象的访问
这里我们通过python manage.py shell 来进行
先导入数据模型
 
通过s1的学院信息
 
Student的模型类中我们有定义department的属性,所以当我们去访问的时候,可以直接通过student.department的形式去找到某个学生的所属学院是哪个.
查看一个d1学院的所有学生 ()
  如果模型I有一个ForeignKey,那么该ForeignKey 所指的模型II实例可以通过一个管理器回前面有ForeignKey的模型I的所有实例。默认情况下,这个管理器的名字为foo_set,其中foo 是源模型的小写名称。
  主键查看外键用_set.all()
 
可以在定义时设置related_name 参数来覆盖foo_set 的名称.
 
添加了related_name的参数后,重新打开一个IDLE,
访问时就能直接用设置的参数作为属性了.
这样使用_set的地方就可以用related_time来替换
 
现在给Course添加数据
 
在学生表中再添加一些数据:
 
现在再来查询一下学院1的所有学生
 
处理关联对象的方法
- add(obj1, obj2, ...) 添加的已经存在数据库的数据
 - 添加一指定的模型对象到关联的对象集中。
 
 
注意Course的多对多属性student,现在
使学生1选择了课程1
 
使学生5选择了课程3
 
现在把再学院2的王五换到学院3
 
 
 
- create(**kwargs) 添加不存在的数据 ,将数据直接存入数据库
 - 创建一个新的对象,将它保存并放在关联的对象集返回新创建的对象。
 
学院4来了个新同学小雅
 
 
remove(obj1, obj2, ...)
- 从关联的对象集中删除指定的模型对象。
 - 删除的是关系表中的数据
 
首先先添加一些数据
 
 
 
 
clear() 从关联的对象集中删除所有的对象
 
注意对于所有类型的关联字段,add()、create()、remove()和clear()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。
多表查询——跨关联关系的查询
Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。
若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段:
查询学院名字为‘计算机学院’的学生的信息
# 查询学院名字为‘计算机’的学生的信息
res = Student.objects.filter(department__d_name='计算机')
查询学生名字中包含 '小' 的学生的学院信息
# 查询学生名字中包含 '小' 的学生的学院信息
res = Department.objects.filter(student__s_name__contains='小')
查询学号为1的学生所有的课程
# 查询学号为1的学生所有的课程
res = Course.objects.filter(student__s_id=1)
查询报了课程1的所有的学生
# 查询报了课程1的所有的学生
res = Student.objects.filter(course__c_id=1)
查询报了'python'课程的的学生的所属学院的信息
# 查询报了'python'课程的的学生的所属学院的信息
res = Department.objects.filter(student__course__name='python')
聚合查询
 
分组查询
 
F查询
from django.db.models import Q, F
 
Q查询
 
                    
                
                
            
        
浙公网安备 33010602011771号