关于django 2.x版本中models.ForeignKey() 外键说明

本文深入解析Django模型中ForeignKey的使用方法,包括不同on_delete选项的效果,如CASCADE、PROTECT等,以及如何正确设置外键避免数据不一致问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面是代码

class GroupInfos(models.Model):
    uid = models.AutoField(primary_key=True)
    caption = models.CharField(max_length=32, unique=True)
    ctime = models.DateTimeField(auto_now_add=True, null=True)
    uptime = models.DateTimeField(auto_now=True, null=True)

class UserInfos(models.Model):
    username = models.CharField(max_length=32, blank=True, verbose_name='用户名')
    password = models.CharField(max_length=64, help_text='text')
    email = models.EmailField(max_length=60)
    user_group = models.ForeignKey('GroupInfos', to_field='uid', on_delete='CASCADE')


说明

第一个class创建一个名称为app_groupinfos的表
第二个class创建一个名称为app_userinfos的表

1、ForeignKey 表示设置外健
2、to_field表示外健关联的主键
3、on_delete有多个选项

引用 https://www.cnblogs.com/phyger/p/8035253.html:
在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错:
TypeError: init() missing 1 required positional argument: ‘on_delete’
举例说明:
user=models.OneToOneField(User)
owner=models.ForeignKey(UserProfile)
需要改成:
user=models.OneToOneField(User,on_delete=models.CASCADE) --在老版本这个参数(models.CASCADE)是默认值
owner=models.ForeignKey(UserProfile,on_delete=models.CASCADE) --在老版本这个参数(models.CASCADE)是默认值
参数说明:
on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值
CASCADE:此值设置,是级联删除。
PROTECT:此值设置,是会报完整性错误。
SET_NULL:此值设置,会把外键设置为null,前提是允许为null。
SET_DEFAULT:此值设置,会把设置为外键的默认值。
SET():此值设置,会调用外面的值,可以是一个函数。
一般情况下使用CASCADE就可以了。

那么,这个时候一个group就会对应多个user,属于一对多的类型。
当我们查询一个组有那些用户的时候,就会用到当前的外健,

创建记录

并且,在class中定义了foreignKey之后,group还不存在的同时,user表也因为约束的原因,不能被进行创建

删除记录

并且,在class中定义了foreignKey之后,user中记录存在的同时,group表中的记录也因为约束的原因,不能被进行删除

<think>我们正在处理一个关于Django中如何为`models.ForeignKey`字段赋值的问题。根据Django的ORM,ForeignKey字段表示多对一关系,我们需要为这个字段赋予一个关联模型的实例。步骤:1.首先,确保已经导入了相关的模型。2.获取或创建要关联的对象实例。3.将实例赋值给ForeignKey字段。例如,假设有两个模型:`Author`和`Book`,其中`Book`有一个指向`Author`的字段。模型定义可能如下:```pythonfromdjango.dbimport modelsclassAuthor(models.Model):name= models.CharField(max_length=100)classBook(models.Model):title= models.CharField(max_length=200)author= models.ForeignKey(Author,on_delete=models.CASCADE)```要为Book的author字段赋值,我们需要一个Author的实例。赋值方式:方式1:如果已经有一个Author实例,直接赋值。```pythonauthor_instance= Author.objects.get(name='J.K. Rowling')book =Book(title='HarryPotter')book.author= author_instancebook.save() ```方式2:在创建Book对象时通过字段赋值。```pythonauthor_instance =Author.objects.get(name='J.K.Rowling') book= Book.objects.create(title='Harry Potter', author=author_instance)```注意:字段在数据库中存储的是关联对象的主值,但在Django中我们操作的是对象实例。如果使用表单,我们可以通过表单的字段来赋值,但需要确保表单中该字段接受的是关联对象的主值(通常通过选择框)。另,在Django Admin中,ForeignKey字段通常显示为下拉选择框,选择已存在的Author实例即可。参考站内引用:引用[1]提到了在ModelForm中设置`fields='__all__'`,这样表单会包含所有字段,包括字段,然后我们可以通过表单提交来赋值。引用[2]提到了Django的认证和权限系统,其中用户和组的关系也是通过关联,创建用户和组时同样需要为字段赋值。因此,无论是通过代码直接操作模型,还是通过表单,我们都需要为ForeignKey字段提供关联模型的一个实例。相关问题:1.如何查询ForeignKey关联的对象?2.如何在Django表单中处理ForeignKey字段?3.如何通过Django Admin为ForeignKey字段赋值?</think>### Django 中为 ForeignKey 字段赋值的完整指南 在 Django 中为 `models.ForeignKey` 字段赋值时,需要为其提供关联模型的一个**实例对象**(而不是整数 ID 或原始值)。以下是详细方法和示例: #### 方法 1:直接赋值模型实例(推荐) ```python # 获取关联对象实例 author = Author.objects.get(id=1) # 或 get(name='J.K. Rowling') # 创建新对象并赋值 new_book = Book( title='Harry Potter', author=author # 直接赋值实例对象 ) new_book.save() ``` #### 方法 2:通过主赋值(需额查询) ```python # 获取主值 author_id = Author.objects.get(name='George R.R. Martin').id # 赋值时需重新获取实例 new_book = Book( title='A Game of Thrones', author_id=author_id # 使用 author_id 字段 ) new_book.save() ``` #### 方法 3:在 ModelForm 中赋值 当使用表单时,Django 会自动处理 ForeignKey 字段: ```python # forms.py class BookForm(forms.ModelForm): class Meta: model = Book fields = '__all__' # 包含所有字段[^1] # views.py def create_book(request): if request.method == 'POST': form = BookForm(request.POST) if form.is_valid(): # 自动处理 ForeignKey 关系 book = form.save() ``` #### 关注意事项: 1. **必须使用对象实例**:直接赋值整数会报错 ```python # 错误示例 ❌ book.author = 1 # 会引发 TypeError ``` 2. **批量创建时**:需先获取所有关联实例 ```python authors = {a.name: a for a in Author.objects.all()} Book.objects.bulk_create([ Book(title='Book1', author=authors['Author A']), Book(title='Book2', author=authors['Author B']) ]) ``` 3. **空值处理**:允许为空时使用 `None` ```python book.author = None # 如果 ForeignKey(null=True) ``` 4. **Django Admin 中**:后台会自动以下拉框显示关联对象[^2] #### 为什么需要实例对象? Django 的 ORM 在保存对象时,会自动提取 ForeignKey 实例的主值存储到数据库,但开发者接口始终使用对象实例以保证数据一致性和便利性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值