Django 保存到多对多字段

Posted

技术标签:

【中文标题】Django 保存到多对多字段【英文标题】:Django saving to ManyToMany fields 【发布时间】:2014-02-26 05:54:35 【问题描述】:

我有一个带有 2 个 ManyToManyField 字段的简单模型类,如下所示:

models.py

class Folder(models.Model):
    user = models.ManyToManyField(User)
    asset = models.ManyToManyField(Asset)

在我看来,我知道用户 ID 和资产 ID。假设用户 ID 为 1,资产 ID 为 30,我该如何注入这一行?我想我不明白如何实例化文件夹,以便我可以保存/更新行。

views.py

def addAssetToMyFolder(request, id=None):
    ''' view is simplified for brevity
    '''
    f = Folder(
        user = 1,
        asset = 30,
    )
    f.save()

【问题讨论】:

【参考方案1】:

要将用户或资产实例与文件夹关联,您需要先保存该文件夹。

为了存储多对多关系,数据库创建了第三个表来存储对象的 ID。

因此,如果您想将用户与文件夹作为多对多关系关联,则它们都应具有自己的 id,然后才能将它们关联成多对多关系。

假设您有两个用户,ID 分别为 10 和 19。 您有一个 ID 为 4 的文件夹,用户 10 和用户 19 与此文件夹相关。在数据库级别,这些关系将如何存储

   folder_id       user_id
       4            10
       4            19

因此,对于每个多对多关系,两个模型的关系表中都有一行。

同样适用于资产。

所以代码应该改成:

def addAssetToMyFolder(request, id=None):
    ''' view is simplified for brevity
    '''
    f = Folder()
    f.save()
    user = User.objects.get(id=1)  # not needed if adding by id
    f.user.add(user)  # or f.user.add(user_id)
    asset = Asset.objects.get(id=30)  # not needed if adding by id
    f.asset.add(asset)  # or f.asset.add(asset_id)

签出:https://docs.djangoproject.com/en/1.6/topics/db/examples/many_to_many/

【讨论】:

以上回答,谢谢解释。我查看了 Django 创建的架构,这使得解决方案更有意义。我假设正在创建一个包含三个字段的表:id |用户 ID | asset_id,但它是 3 个表,其中两个绑定到关系表。【参考方案2】:

因为我真的很讨厌冗余,所以这里有另一个使用动态模型形式的解决方案。好处是更简洁,不需要去获取UserAsset对象,使用相关的pk,只保存一次。

缺点是它对于常见的日常需求来说太过分了。所以你可能应该将@zaphod100.10 的答案标记为正确,但要知道这种方法也存在:

Meta = type('Meta', (), 'model': Folder, 'fields': ['user', 'asset'] )
FolderForm = type('FolderForm', (forms.ModelForm, ), 'Meta': Meta)

data = 'user': ['1'], 'asset': ['30'] #the values need to be a list of strings, representing pks of related objects
f = FolderForm(data)
new_obj = f.save()

【讨论】:

以上是关于Django 保存到多对多字段的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django rest 框架保存多对多字段对象

禁止直接分配到多对多集合的前端。改用 emails_for_help.set()

我们如何在 django 管理搜索字段中搜索多对多字段

Django 多对多字段

通过 Django 中的模型表单保存多对多数据

具有多对多关系的Django表单不保存