如何使用一对多关系保存Django未保存的模型

时间:2013-12-27 20:01:05

标签: python django django-models django-views

我有两个模型之间的Django 1.5一对多关系。它看起来像这样

class Team(models.Model):
    class Meta:
    league = models.ForeignKey(League,related_name="teams")
    ...

class League(models.Model):
    ...

每个联盟可以有一个或多个团队。我正在响应联盟相关URL上的POST请求以及创建(或更新)联盟的过程。团队只能通过联赛间接创建(即不支持团队的POST),每个团队必须有一个联盟。但是我无法让它正常工作。

LeagueSerializer我已覆盖from_native并解析json(我没有TeamSerializer)。当full_clean()出现验证错误时,我返回None(来自from_native())。在我看来,在致电LeagueSerializer.is_valid()后,我会检查LeagueSerializer.object是否不是None,如果不是,我会致电LeagueSerializer.save()。当我不改变联盟的球队时,这似乎很有效。以下是来自views.py的片段(根据TankorSmash的要求)

def league_submit(request):
    if request.method == 'POST':
        #pass the incoming post data to league serializer
        serializer = LeagueSerializer(data=request.body)
        if serializer.is_valid():
            if serializer.object is None:
                print "something went awry in from_native. invalid/bad data in post"
            else:
                print "things seemed to have been ok in from_native"
                serializer.save()

任何通过调用league.teams.add(new_team)将团队添加到未保存的联盟实例的尝试都会因完整性错误而失败

IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails 

如何使用一对多外键关系保存未保存的League?我想保持当前的处理流程。

编辑 - 我已经找到了解决方法。

1.我必须暂时关联来自DB的League对象,以便我可以调用new_team.full_clean()。完成后,我设置new_team.league = new_league。这样我就可以验证new_team,它最终将与不在DB中的new_league相关联。

2.为了将new_team传递给我的视图,我在联盟模型中引入了unsaved_objects非模型列表。视图调用League对象上的save(),然后迭代unsaved_objects并调用每个对象的保存。

以下是我迄今为止所学到的内容--Django 1.5没有提供一种方法让你创建一个新的联盟,一个新的团队并将团队与联盟联系起来并在任何一个对象上调用一次保存(无论如何)序列化或模型)拯救联盟,它与团队和团队的关系。 Django需要保存联盟,然后保存在Team。

我将上述内容称为解决方法,因为它完全不符合我的目的。例如,如果团队保存失败,DB将已经处理了联盟保存,因此要求我跟踪(a)何时创建new_league所以我可以在更新现有联赛时删除新联赛(b)以前的联赛内容,以便我可以恢复到以前的联赛。如果我可以在save()调用之间进行事务处理,那么就可以解决这个问题。

不断地为临时联赛查询数据库是一种浪费。

1 个答案:

答案 0 :(得分:0)

  

任何尝试通过调用将团队添加到未保存的联盟实例   league.teams.add(new_team)因完整性错误而失败

如果我理解正确的话,你会尝试将Team保存到数据库但不会完成联盟的外键。尝试将blank=True, null=True添加到定义Team的{​​{1}}模型的行中,以便在没有现有league的情况下保存Team以链接到:< / p>

League

但我首先想到的是,如果没有第二把钥匙,你就无法保存一个模型。如果没有明确说明,你就无法向数据库保存“没有”。