一、三种方式
全自动(不推荐)
- 优点:django orm会自动创建第三张表
- 缺点:只会创建两个表的关系字段,不会再额外添加字段,可扩展性差
class Book(models.Model):
# ...
authors = models.ManyToManyField(to='Author')
class Author(models.Model):
# ...
pass
纯手动(不推荐)
- 优点:第三张表可以根据自己的要求随意添加额外的字段
- 缺点:orm在查询的时候,很多方法不支持,查询非常麻烦
class Book(models.Model):
# ...
pass
class Author(models.Model):
# ...
pass
class Book_Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
# ...
pass
半自动
- 优点:手动建表,但要告诉orm第三张表是自己建的,orm只需要提供查询方法
- 缺点:虽然可以使用orm的查询方法,但不支持使用add(), set(), remove(), clear()
class Book(models.Model):
# ...
authors = models.ManyToManyField(
to='Author',
through='Book_Author',
through_fields=('book', 'author')
)
class Author(models.Model):
# ...
books = models.ManyToManyField(
to='Book',
through='Book_Author',
through_fields=('author', 'book')
)
class Book_Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
# ....
二、项目应用
class Num(models.Model):
name = models.CharField(max_length=50, verbose_name='范围')
class Meta:
ordering = ['id']
db_table = 'tb_value'
verbose_name_plural = verbose_name = '频率'
class Key(models.Model):
# 多对多的关系表
num= models.CharField(verbose_name="值", max_length=25, null=True, blank=True)
# 默认反向应用的名称是:(当前类名称小写)_set,可以用related_name来指定
nums= models.ManyToManyField(
Frequency,
db_table='tb_num_and_nums',
related_name="num_range",
verbose_name="取值范围"
)
num_id_list = judge_num.judge(None, num)
# 写入数据库
key_obj = Audio(description=description, num=num)
key_obj.save()
for num_id in num_id_list:
num_obj= Num.objects.get(id=num_id)
keys_obj.num.add(num_obj)
ForeignKey参数设置
参数设置
to
:关联的表
on_delete
:当该表中的某条数据删除后,关联外键的操作
related_name
:反查参数,设置后可以在被关联表中通过该字段反查外键所在表,默认:set_表名
to_field
:
- 默认主键,因为mysql只支持主键作为外键,就算你没显式的创建主键,Django会给你自动创建,
- 如果你是DB-first,且没创建主键:数据库默认使用隐藏字段:DB_ROW_ID作为主键
on_delete参数设置
CASCADE
:级联删除,当关联表中的数据删除时,该外键也删除
PROTECT
: 保护模式,如果采用该选项,删除的时候,会抛出ProtectedError错误。
SET_NULL
:
- 置空模式,删除的时候,外键字段被设置为空
- 前提就是blank=True, null=True,定义该字段的时候,允许为空。
SET_DEFAULT
: 设置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
SET()
: 自定义一个值,该值当然只能是对应的实体
参考:https://www.cnblogs.com/zj420255586/p/11761007.html
评论区