django如果一条记录有一些自己的外键值,则对外键记录进行操作

时间:2013-12-31 03:50:09

标签: django

为了避免更改大量现有代码,我尝试将自己的外键添加到模型中,然后记录上的操作(filter,get,update,save,...)将自动执行“真实记录”,如果它有自己的外键值。我需要做什么?

class Person(models.Model):
    name = models.CharField(null=True,blank=True,max_length=50)
    real_one = models.ForeignKey('self',null=True,blank=True)

我期待:

tom = Person.objects.create(name='Tom') # id=1
Person.objects.create(name='someone', real_one=tom) # id=2

someone = Person.objects.filter(name='someone')[0]
print someone.id # 1
print someone.name # Tom
someone.name = 'Jack'
someone.save()
tom = Person.objects.filter(name='Tom')[0] # sorry, this line added late
print tom.name # 'Jack'

1 个答案:

答案 0 :(得分:0)

恕我直言,你试图以非规范化的方式做到这一点,它可能不适合你。你能做的一件事是:

class Person(models.Model):
    name = models.CharField(null=True,blank=True,max_length=50)
    real_one = models.ForeignKey('self',null=True,blank=True)

    @property
    def real_name(self):
        if(self.real_one):
            return self.real_one.real_name
        else:
            return self.real_name

    @real_name.setter
    def real_name_setter(self, val):
        if(self.real_one):
            self.real_one.real_name = val
            self.real_one.save()
        else:
            self.real_name = val
            self.save()

但这会产生大量的数据库事务。还要注意setter的 required 副作用,因为它必须立即保存记录,以免它忘记更改了哪条记录。这仍然存在一个问题,即以下情况不起作用:

someone.name = 'Jack'
someone.save()
print tom.name # 'Tom' <-- The 'tom' object now has stale data!

一个对象正在改变,但(就Python而言)一个完全不同的对象实际上正在被改变。没有可靠的方法可以在不改变Django和创建混乱的情况下执行此操作(Django必须在内部跟踪引用给定记录的每个对象,这会破坏垃圾收集器,Django的查询集惰性评估生成器,甚至可能是事务)

您最好的选择是尝试不同的方法,或者接受您的示例不起作用的事实。如果您坚持使用此架构,则每个filterexclude查询集调用以及可能的其他调用都需要了解此别名。

恕我直言,你在改变架构方面要好得多:一个有名字的桌子和一个有每个人“真实”信息的桌子。名称表具有信息表的外键。

如果您正在尝试做其他事情,那么您需要在问题中更清楚地解释