【问题标题】:How to populate a recursive m2m field如何填充递归 m2m 字段
【发布时间】:2025-12-25 06:45:12
【问题描述】:

我的模型中有一个带有递归 m2m 字段的类

我的model.py

class Person(models.Model):
    name = models.CharField(_('name'), max_length=64)
    slug = models.SlugField(primary_key=True)
    friends = models.ManyToManyField('self', 
        related_name='nation_friends', symmetrical=False)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Person, self).save(*args, **kwargs)

我用脚本填充我的数据库。当实例引用尚未创建的实例时,问题就出现了

我的script.py

john = add_person('John', ['marc', 'philip'])
#john = add_person('John', [marc, philip]) #this gives immediately error: marc is not definited
marc = add_person('Marc', [])
philip = add_person('Philip', [])

def add_person(name, friends):
    p=Person.objects.get_or_create(name=name)[0]
    lista_friends = []
    for f in friends:
        lista_friends.append(f)
    p.friends.set(lista_friends)

这是错误(我的翻译,在原文下面)

django.db.utils.IntegrityError: ERROR:  the INSERT or the UPDATE on the
table "core_person_friends" break the constrain of external key "core_person_friends_to_person_id_ab3c358a_fk_core_person_slug"
DETAIL:  The key (to_person_id)=(marc) is not present on the table "core_person".

原文:

django.db.utils.IntegrityError: ERRORE:  la INSERT o l'UPDATE sulla 
tabella "core_person_friends" viola il vincolo di chiave esterna "core_person_friends_to_person_id_ab3c358a_fk_core_person_slug"
DETAIL:  La chiave (to_person_id)=(marc) non ?? presente nella tabella "core_person".

也许问题是因为 slug 字段?

【问题讨论】:

    标签: python django many-to-many recursive-datastructures


    【解决方案1】:

    您应该传递一个对象列表,而不仅仅是值。按名称获取 Person 对象并添加这些对象。您正在尝试添加人名。还要确保名称具有相同的大小写,否则将为同一个人创建多次实例。

    john = add_person('John', ['Marc', 'Philip'])
    marc = add_person('Marc', [])
    philip = add_person('Philip', [])
    
    def add_person(name, friends):
        p = Person.objects.get_or_create(name=name)[0]
        lista_friends = []
        for f in friends:
            lista_friends.append(Person.objects.get_or_create(name=f)[0])
        p.friends.set(lista_friends)
    

    【讨论】: