django反向外键是空的

时间:2014-01-17 20:20:00

标签: django django-models

所有

我无法弄清楚为什么这不起作用。

models.py:

from django.db import models

class MyModel(models.Model):
    name         = models.CharField(max_length=64,blank=False,null=False)
    parent_model = models.ForeignKey('self',null=True,blank=True,related_name="child_models")

    def __unicode__(self):
        return u'%s' % (self.name)

    def add_child(self,child):
        child.parent_model = self

python manage.py shell:

>>> foo = MyModel(name='foo')
>>> bar = MyModel(name='bar')
>>> foo.add_child(bar)
>>> bar.parent_model
<MyModel: foo>
>>> foo.child_models.all()
[]

为什么在设置外键“parent_model”时反向外键“child_models”为空?

由于


Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from questionnaire.models import *
>>> foo = TestModel(name='foo')
>>> bar = TestModel(name='bar')
>>> foo.save()
>>> bar.save()
>>> foo.add_child(bar)
>>> bar.get_parent()
<TestModel: foo>
>>> foo.get_children()
[]

def myView(request):
  foo = MyModel(name='foo')
  bar = MyModel(name='bar')
  foo.add_child(bar)

  # I don't want to have to save foo or bar before I know that the data is correct,
  # or that the user has even pressed submit

  if request.method == "POST":
    form = MyForm(request.POST)
    if form.is_valid():
      # somewhere in here is where I want to do the saving to the db
      instance = form.save(commit=False)
      instance.save()
      form.save_m2m()
    else:
      form = MyForm(instance=foo)

  return render_to_response('my_template.html', {"form":form}, context_instance=RequestContext(request))

1 个答案:

答案 0 :(得分:1)

有两个可能的原因:

使用add_child方法:

这不是你的问题,但你也可以来这个

def add_child(self,child):
    child.parent_model = self

你没有保存child。因此,您的更改不会反映到数据库中。但由于您的querysets也是对象:

>>> foo.add_child(bar)
>>> bar.parent_model
<MyModel: foo>

bar对象保留其新数据,但由于您未将其保存到数据库,因此不会反映到foo

您正在处理过时的数据:

这是你的问题

>>> foo = TestModel(name='foo')
>>> bar = TestModel(name='bar')
>>> foo.save()
>>> bar.save()

您保存它们,foobar对象都带有与其相关数据库记录相同的值。

 >>> foo.add_child(bar)

您更新bar 对象,但请勿保存。因此,每个数据库数据都不会更新,只会更改bar个对象。

>>> bar.get_parent()
<TestModel: foo>
>>> foo.get_children()
[]

您的bar对象已更新。由于您没有将更改保存到数据库并刷新相关对象(再次从数据库中检索它们),因此您不会更新。因此,您的foo对象仍然已过期

您必须再次保存数据并从数据库中检索所需的对象...

>>> foo = TestModel(name='foo')
>>> bar = TestModel(name='bar')
>>> foo.save()
>>> bar.save()  # Instead of make a second save, you can discard this save step and save after `add_child` 
>>> foo.add_child(bar)
>>> bar.save()
>>> foo = MyModel.objects.get(name="foo")