合并模型,Django 1.11

时间:2017-05-24 15:43:05

标签: django django-orm

从Django 1.8升级到1.11之后,我一直在寻找合并某些记录的方法 - 例如,某些模型有多个条目具有相同的name字段。这里有一个答案,似乎有我需要的东西:

https://stackoverflow.com/a/41291137/1195207

我用这样的模型尝试过它:

class GeneralType(models.Model):
    #...
    domains = models.ManyToManyField(Domain, blank=True)
    #...

class Domain(models.Model):
    name = models.TextField(blank=False)
    #...

...其中Domain有各种名称重复的记录。但是,它在指出的地方失败了:

def merge(primary_object, alias_objects=list(), keep_old=False):
    """
    Use this function to merge model objects (i.e. Users, Organizations, Polls,
    etc.) and migrate all of the related fields from the alias objects to the
    primary object.  This does not look at GenericForeignKeys.

    Usage:
    from django.contrib.auth.models import User
    primary_user = User.objects.get(email='good_email@example.com')
    duplicate_user = User.objects.get(email='good_email+duplicate@example.com')
    merge(primary_user, duplicate_user)
    """

    # ...snip....

    for alias_object in alias_objects:
        for related_object in alias_object._meta.related_objects:
            related_name = related_object.get_accessor_name()
            if related_object.field.many_to_one:
                #...snip...
            elif related_object.field.one_to_one:
                #...snip...
            elif related_object.field.many_to_many:
                related_name = related_name or related_object.field.name
                for obj in getattr(alias_object, related_name).all():
                    getattr(obj, related_name).remove(alias_object) # <- fails here
                    getattr(obj, related_name).add(primary_object)

问题显然是'GeneralType' object has no attribute 'generaltype_set'。向GeneralType添加related_name并不能解决此问题 - 脚本以相同的方式失败,但引用了我现在给出的名称。我不太确定Django在这里做什么,所以欢迎任何建议。

编辑:

在Django shell中,我可以成功地从Domain引用GeneralType,所以它是关于上面那个我没有得到的脚本的东西。例如:

>>> d = Domain.objects.first()
>>> d
<Domain: 16s RNA>
>>> d.generaltype_set  
<django.db.models.fields.related_descriptors.ManyRelatedManager object at 0x11175ba90>
>>> d.generaltype_set.first()
<GeneralType: Greengenes>
>>> getattr(d,'generaltype_set')
<django.db.models.fields.related_descriptors.ManyRelatedManager object at 0x10aa38250>

1 个答案:

答案 0 :(得分:0)

我设法找到了解决方法。如果我在脚本的generaltype.domains部分引用getattr(obj, related_name),似乎一切都会起作用,所以我在上面问题中标记为失败的行之前修改如下:

if obj.__class__.__name__ == 'GeneralType':
    related_name = 'domains'

似乎所有东西都应该运行。