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查询

 

posted @ 2020-08-14 19:12  inhocho  阅读(28)  评论(0)    收藏  举报