In Django I have a model where one of the fields (tags) is a ManyToManyField:
class MyModel(models.Model):
id = models.CharField(max_length=30, primary_key=True)
title = models.CharField(max_length=300, default='')
author = models.CharField(max_length=300)
copy = models.TextField(blank=True, default='')
tags = models.ManyToManyField(Tag)
I have a custom management task below where I'm getting all of the instances of the MyModel table on a server and using that to replace the instances of the MyModel table on my local server. (I'm running this custom management task from my local)
Here's what I'm trying so far.
However I'm getting this error: CommandError: Direct assignment to the forward side of a many-to-many set is prohibited. Use tags.set() instead.
How can I update the tags field that's a ManyToMany field?
from bytes.models import MyModel
class Command(BaseCommand):
def handle(self, *args, **options):
try:
// get queryset of MyModel instances from server
queryset = MyModel.objects.using('theserver').all()
// loop through that queryset and create a list of dictionaries
mymodel_list = [
{
'id': mymodel['id'],
'title': mymodel['title'],
'author': mymodel['author'],
'copy': mymodel['copy'],
'tags': mymodel['tags']
}
for mymodel in queryset
]
//delete all objects in the local MyModel table
MyModel.objects.all().delete()
//replace with MyModel instances from server
new_mymodel = [
MyModel(
id=mymodel['id'],
title=mymodel['title'],
author=mymodel['author'],
copy=mymodel['copy'],
tags=mymodel['tags'] <--- causing error
)
for mymodel in mymodel_list
]
MyModel.objects.bulk_create(new_mymodel)
CodePudding user response:
ManyToMany fields are working differently from any other field. You cannot simply copy it's values, especially from strings. You can try add objects in a loop just after after creating MyModel:
//replace with MyModel instances from server
new_mymodels = []
for mymodel in mymodel_list:
new_mymodel = MyModel(
id=mymodel['id'],
title=mymodel['title'],
author=mymodel['author'],
copy=mymodel['copy']
)
for tag in mymodel['tags']:
new_mymodel.tags.add(tag)
new_mymodels.append(new_mymodel)
MyModel.objects.bulk_create(new_mymodel)
It is possible, that you will have to firstfully find the Tag object before .add() method. It depends on values in mymodel['tags'].
