将表单对象传递给同一页面/视图中的其他表单()

时间:2018-02-13 20:15:21

标签: django django-forms

如何在视图的表单验证块中引用上面刚创建的表单对象?

如果您有共享模型,则使用其他两个可选的相关模型:

class Tree(models.Model):
  type= ...
class Picture(models.Model):
  camera = ...
  tree=models.ForeignKey(Tree)
class Lumber(models.Model):
  used_to_build = ...
  tree=models.ForeignKey(Tree)
  picture=models.ForeignKey(Picture, blank=True, null=True)
class Bird(models.Model):
  species = ...
  tree=models.ForeignKey(Tree)
  picture=models.ForeignKey(Picture, blank=True, null=True)

您可以在自己的视图中创建Bird和Lumber,当然也可以引用特定的树。

如果您有视图,并且创建了一个表单,可以创建树,木材和鸟的图片,并且您希望将新创建的图片传递给Lumber和BirdForm,因为在这种情况下,我们知道木材和鸟在哪张图片:

def treeView(request):   
  #Post
    pictureForm = PictureForm(instance=tree, prefix='treeForm')
    # This is what I am trying to figuere out
    # lumberForm = LumberForm(instance=tree, picture=pictureForm.object prefix='lumberForm')
    lumberForm = LumberForm(instance=tree, prefix='lumberForm')
    birdForm = BirdForm(instance=tree, prefix='birdForm')

如何将创建的实际对象传递给可以选择接受相关对象的其他表单?即

                                                ▼ how do you pass in the form object from above?
 lumberForm = LumberForm(instance=tree, picture=pictureForm.object, prefix='lumberForm')
  • 在下一步之前保存后,您是否需要查询? (似乎是竞争条件)
  • 设置一个try / catch?
  • 我尝试通过返回对象覆盖表单中的save(),但是pictureForm只是HTML,所以我不知道如何获取obj ...

帮助你微笑的相关图片:) [Some lumber from a tree with a(n absent) bird [1] 专辑:https://www.facebook.com/media/set/?set=a.10101895369321847.1073741831.36619363&type=1&l=70c30792e3

1 个答案:

答案 0 :(得分:1)

我不能100%确定我是否正确理解了您要解决的问题,但我会尝试提供解决方案。

我考虑以下假设:

  • 您已拥有Tree实例
  • PictureLumberBird将与相同的Tree
  • 相关联
  • 创建的Picture将与同一视图中创建的LumberBird相关联。

基本上你要做的是,将所有内容包装在同一个数据库事务中,让它下雨。

from django.db import transaction
from django.shortcuts import render, redirect

def treeView(request, pk):
    tree = Tree.objects.get(pk=pk)  # you tell me how you get your tree instance

    if request.method == 'POST':
        pictureForm = PictureForm(request.POST, prefix='treeForm')
        lumberForm = LumberForm(request.POST, prefix='lumberForm')
        birdForm = BirdForm(request.POST, prefix='birdForm')

        if pictureForm.is_valid() and lumberForm.is_valid() and birdForm.is_valid():
            with transaction.atomic():
                picture = pictureForm.save(commit=False)
                picture.tree = tree
                picture.save()

                lumber = lumberForm.save(commit=False)
                lumber.tree = tree
                lumber.picture = picture
                lumber.save()

                bird = birdForm.save(commit=False)
                bird.tree = tree
                bird.picture = picture
                bird.save()
            return redirect('success_view')
    else:
        pictureForm = PictureForm(prefix='treeForm')
        lumberForm = LumberForm(prefix='lumberForm')
        birdForm = BirdForm(prefix='birdForm')

    return render(request, 'tree_form.html', {
        'tree': tree,
        'pictureForm': pictureForm,
        'lumberForm': lumberForm,
        'birdForm': birdForm
    })