【问题标题】:Merging Model Objects in Many to Many Relationship在多对多关系中合并模型对象
【发布时间】:2016-05-13 12:48:44
【问题描述】:

我正在尝试将我的 Django 应用程序中的一些对象合并在一起。我痛苦地从一个 Wordpress 网站迁移数据。该站点是针对警察的事件的档案,我使用两个模型(事件,官员)以多对多的关系与(详细信息)作为中间模型。这是我的models.py:

from __future__ import unicode_literals
from django.db import models

class Officer(models.Model):
    first_name = models.CharField(max_length=80, blank=True)
    last_name = models.CharField(max_length=80, blank=True)
    badge = models.IntegerField(blank=True)
    department = models.CharField(max_length=50, blank=True)

    def __unicode__(self):
        return self.last_name + ', ' + self.first_name

class Incident(models.Model):
    officers2 = models.ManyToManyField(Officer, through='Details')
    case_number = models.CharField(max_length=50, blank=True)

    OFFICE_CHOICES = (
    ('CRA', 'Civilian Review Authority'),
    ('IA', 'Internal Affairs'),
    ('OPCR', 'Office of Police Conduct Review'),
    )
    office = models.CharField(max_length=10,
    choices=OFFICE_CHOICES,
    )

    def __unicode__(self):
        return self.case_number

class Details(models.Model):
    officer = models.ForeignKey(Officer, on_delete=models.CASCADE)
    incident = models.ForeignKey(Incident, on_delete=models.CASCADE)
    allegation = models.CharField(max_length=50, blank=True)
    finding = models.CharField(max_length=50, blank=True)
    action = models.CharField(max_length=50, blank=True)


    def __unicode__(self):
        return unicode(self.officer.first_name) + ' '+ unicode(self.officer.last_name)+ ', ' + unicode(self.incident)

    class Meta():
        verbose_name_plural = "details"

问题是目前有相同案件编号的重复事件,涉及不同的警官。我正在尝试将这些合并到一个事件中,同时保留详细信息中的所有信息。这是我尝试过的脚本,但效果不太好。

from __future__ import unicode_literals
from police_archive.models import Incident, Details, Officer
from django.db.models import Count



def run() :

    #get list of duplicates
    list=Incident.objects.values('case_number').annotate(case_number_count=Count('case_number')).exclude(case_number_count=1)
    g= []

    #make list of case numbers
    for item in list:
        g.append(item['case_number'])



    #first entry was empty, remove first entry
    for number in g[1:] :

        #get list of incident objets
        old_incidents=Incident.objects.filter(case_number=number);

        #make new object to replace old ones
        new_incident = Incident(case_number=number)
        new_incident.office=old_incidents[0].office

        #filter out all details which match one of the incidents
        details_list=Details.objects.none()
        for incident in old_incidents:
            print incident.officer2
            results=Details.objects.filter(incident=incident)
            details_list = details_list | results

        #delete old_incidents so that details can be modified
        old_incidents.delete()

        #create new details objects pointing to new incident object, delete old details object
        for details in details_list:
            new_details = Details(incident=new_incident,officer=details.officer, allegation=details.allegation, finding=details.finding, action=details.action)
            new_details.save()
            details.delete()
            #details.save()
        new_incident.save()

此脚本的结果是正确创建事件对象,但未创建详细信息对象。我已经在 shell 中尝试了脚本的微型版本,并取得了很好的效果。我目前没有想法;有的话请告诉我。

谢谢!

【问题讨论】:

    标签: python django django-orm


    【解决方案1】:

    您需要先保存new_incident,然后才能保存详细信息。在新事件进入数据库之前,您正在保存新的详细信息。

    【讨论】:

    • 我其实也试过这种方式,结果还是一样。
    • 除非我误解了您的代码,否则它总是会从数据库中删除原始详细信息。如果您需要对代码进行任何更改,则必须从备份中恢复数据库才能重试。这是你在做什么,还是我错过了什么?
    • 不,这是本意。删除旧的,保存新的。最初我只是尝试修改旧的,但这不起作用,所以我尝试了帮助。我一直在从备份中恢复该数据。感谢您和我一起看这个!
    • 在你问题中写的代码中,在你保存new_incident之前,new_incident.id应该是None。如果你保存new_details 没有incident 的外键,它应该会给你一个错误消息。如果你没有收到错误,那让我认为details_list 一定是空的。
    猜你喜欢
    • 2021-10-24
    • 2014-02-02
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2018-01-04
    • 2020-12-21
    • 1970-01-01
    相关资源
    最近更新 更多