Django:如何在定制的Django管理任务中更新ManyToManyfield?

2022-04-17 00:00:00 python django django-orm manytomanyfield

问题描述

在Django中,我有一个模型,其中一个字段(tags)是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)
我下面有一个自定义管理任务,我将在其中获取服务器上MyModel表的所有实例,并使用该任务替换我的本地服务器上的MyModel表的实例。(我从本地运行此自定义管理任务)

以下是我目前正在尝试的内容。

但是,我收到了这个错误:CommandError:禁止直接赋值到多对多集合的前端。请改用tag s.set()。

如何更新作为ManyToMany字段的tags字段?

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)

解决方案

ManyToMany字段的工作方式与任何其他字段不同。您不能简单地复制它的值,尤其是从字符串复制。您可以尝试在创建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)
有可能在.add()方法之前,您必须首先找到Tag对象。它取决于mymodel['tags']中的值。

相关文章