Django:合并对象 [英] Django: merging objects

查看:170
本文介绍了Django:合并对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的模型:

$ p $ class Place(models.Model):
name = models.CharField(
city = models.ForeignKey(City)
address = models.CharField(max_length = 255,db_index = True)
#等等

因为我从很多来源导入它们,并且我的网站用户可以添加新的位置,所以我需要从管理界面合并它们的方法。问题是,名称是不是很可靠,因为他们可以拼写在许多不同的方式,等
我习惯使用这样的东西:

  class Place(models.Model):
name = models.CharField(max_length = 80,db_index = True)#canonical $ b $ city = models.ForeignKey(City)
地址= models.CharField(max_length = 255,db_index = True)
#等等
$ b $ class className(models.Model):
name = models.CharField(max_length = 80,db_index = True)
place = models.ForeignKey(Place)

这个

  Place.objects.get(placename__name ='圣保罗大教堂',city = london)

并像这样合并

  class PlaceAdmin(admin.ModelAdmin):
action =('merge',)
$ b def merge(self,request,queryset):
main = queryset [ 0]
tail = queryset [1:]

PlaceName.obje (place_in = tail).update(place = main)
SomeModel1.objects.filter(place__in = tail).update(place = main)
SomeModel2.objects.filter(place__in = tail) .update(place = main)
#... etc ...

在尾巴里:
t.delete()

self .message_user(请求,%s与其他地方合并,现在你可以给它一个规范的名称。)
merge.short_description =合并地点

正如您所看到的,我必须使用FK更新所有其他模型以放置新值。但这不是一个很好的解决方案,因为我必须添加每个新的模型到这个列表。



在删除它们之前,如何将所有外键级联更新?



也许还有其他解决方案可以做/避免合并

解决方案

如果有人碰撞,这里是真正的通用代码:

$ $ $ $ $ c $ def def(self,request,queryset)
main = queryset [0]
tail = queryset [1:]

related = main._meta.get_all_related_objects()

valnames = dict()
for r in相关:
valnames.setdefault(r.model,[])。append(r.field.name)

放置在尾部:
for model_name,field_names in valnames.iteritems():
for field_name in field_names:
model.objects.filter(** {field_name:place})。update(** {field_name:main})

place.delete()

self.message_user(request,%s is me与其他地方,现在你可以给它一个规范的名称。%主要)


I have such model:

class Place(models.Model):
    name = models.CharField(max_length=80, db_index=True)
    city = models.ForeignKey(City)
    address = models.CharField(max_length=255, db_index=True)
    # and so on

Since I'm importing them from many sources, and users of my website are able to add new Places, I need a way to merge them from an admin interface. Problem is, name is not very reliable since they can be spelled in many different ways, etc I'm used to use something like this:

class Place(models.Model):
    name = models.CharField(max_length=80, db_index=True) # canonical
    city = models.ForeignKey(City)
    address = models.CharField(max_length=255, db_index=True)
    # and so on

class PlaceName(models.Model):
    name = models.CharField(max_length=80, db_index=True)
    place = models.ForeignKey(Place)

query like this

Place.objects.get(placename__name='St Paul\'s Cathedral', city=london)

and merge like this

class PlaceAdmin(admin.ModelAdmin):
    actions = ('merge', )

    def merge(self, request, queryset):
        main = queryset[0]
        tail = queryset[1:]

        PlaceName.objects.filter(place__in=tail).update(place=main)
        SomeModel1.objects.filter(place__in=tail).update(place=main)
        SomeModel2.objects.filter(place__in=tail).update(place=main)
        # ... etc ...

        for t in tail:
            t.delete()

        self.message_user(request, "%s is merged with other places, now you can give it a canonical name." % main)
    merge.short_description = "Merge places"

as you can see, I have to update all other models with FK to Place with new values. But it's not very good solution since I have to add every new model to this list.

How do I "cascade update" all foreign keys to some objects prior to deleting them?

Or maybe there are other solutions to do/avoid merging

解决方案

If anyone intersted, here is really generic code for this:

def merge(self, request, queryset):
    main = queryset[0]
    tail = queryset[1:]

    related = main._meta.get_all_related_objects()

    valnames = dict()
    for r in related:
        valnames.setdefault(r.model, []).append(r.field.name)

    for place in tail:
        for model, field_names in valnames.iteritems():
            for field_name in field_names:
                model.objects.filter(**{field_name: place}).update(**{field_name: main})

        place.delete()

    self.message_user(request, "%s is merged with other places, now you can give it a canonical name." % main)

这篇关于Django:合并对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆