我正在尝试编写管理操作来复制下面的Circus模型。
到目前为止,我的代码存在的问题是,当我尝试运行它时,我收到类似的错误:
无法在指定中介的ManyToManyField上设置值 模型。
以下是我的模特:
class Clown(models.Model):
name = models.CharField(max_length=255)
class Circus(models.Model):
clowns = models.ManyToManyField(Clown, blank=True, through='WorkedAt')
name = models.CharField(max_length=255)
class WorkedAt(models.Model):
clown = models.ForeignKey(Clown)
circus = models.ForeignKey(Circus)
以下是admin.py中的代码:(尝试关注the advice here)
class CircusAdmin(BaseAdmin):
def duplicate(self, request, queryset):
for obj in queryset:
old_clowns = obj.clowns.all()
obj.id = None
obj.name += ' (copy)'
obj.save()
obj.clowns = old_clowns
duplicate.short_description = "Duplicate Selected Circuses"
actions = [duplicate]
答案 0 :(得分:3)
当您使用中间through
表时,您使用相关对象管理器(即obj.clowns
)的能力是有限的。正如docs所说:
与普通的多对多字段不同,您不能使用添加,创建或分配(即beatles.members = [...])来创建关系....简单的添加,创建和分配调用不提供指定此额外细节的方法。因此,对于使用中间模型的多对多关系,它们被禁用。创建此类关系的唯一方法是创建中间模型的实例。
因此,不是分配相关的经理,而是自己创建新的中间对象:
def duplicate(self, request, queryset):
for obj in queryset:
old_workedat = list(obj.workedat_set.all())
obj.id = None
obj.name += ' (copy)'
obj.save()
new_workedat = [WorkedAt(circus_id=obj.id, clown_id=wa.clown_id)
for wa in old_workedat]
WorkedAt.objects.bulk_create(new_workedat)