Django saving to ManyToMany fields

走远了吗. 提交于 2019-12-13 20:34:05

问题


I have a simple model class with 2 ManyToManyField fields like this:

models.py

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

In my view, I know the user ID and the asset ID. Say the user ID is 1 and the asset ID is 30, how do I inject this row? I guess I don't understand how to instantiate Folder so I can save/update the row.

views.py

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

回答1:


To associate a user or asset instance with a folder you need to first save the folder.

To store a many to many relationship the database creates a third table which stores the ids of the objects.

So if you want to relate a user to a folder as a many to many relationship, both of them should have their own ids before they can be related as many to many.

Say you have two users with ids 10 and 19 respectively. You have one folder with id 4 and user 10 and user 19 are related to this folder. At the db level this how these relations will be stored

   folder_id       user_id
       4            10
       4            19

so for each many to many relation there is one row in the relations table for the two models.

Same will be valid for asset.

So the code should be changed to:

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)

check out : https://docs.djangoproject.com/en/1.6/topics/db/examples/many_to_many/




回答2:


Because I reallllly hate redundancy, here's a another solution using a dynamic modelform. The benefits are it's neater, you don't need to fetch the User and Asset objects, you use the related pk and you only save once.

The drawback is that it's a retarded overkill for the common everyday need. So you should probably mark @zaphod100.10 answer as correct, but know that this method also exists:

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()


来源:https://stackoverflow.com/questions/21515621/django-saving-to-manytomany-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!