为了避免更改大量现有代码,我尝试将自己的外键添加到模型中,然后记录上的操作(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'
答案 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的查询集惰性评估生成器,甚至可能是事务)
您最好的选择是尝试不同的方法,或者接受您的示例不起作用的事实。如果您坚持使用此架构,则每个filter
和exclude
查询集调用以及可能的其他调用都需要了解此别名。
恕我直言,你在改变架构方面要好得多:一个有名字的桌子和一个有每个人“真实”信息的桌子。名称表具有信息表的外键。
如果您正在尝试做其他事情,那么您需要在问题中更清楚地解释 。