一起提交 2 个表单,将其中一个的主键作为外键传递给另一个

Posted

技术标签:

【中文标题】一起提交 2 个表单,将其中一个的主键作为外键传递给另一个【英文标题】:submitting 2 forms together, passing primary key from one as foreign key in other 【发布时间】:2016-05-07 08:20:45 【问题描述】:

我使用 python 和 django 从一个 html 模板中的 2 个单独的 modelForms 创建了一个表单。型号:

class Action(models.Model):
    name = models.CharField("Action name", max_length=50)
    keywords = models.CharField("Keywords", max_length=50)
    object = models.CharField("Object", max_length=50, blank=True, null=True)
    uploadDate = models.DateField("Date", default=get_current_date)
    UploadedBy = models.CharField("UploadedBy", max_length=50, default="")

class Image(models.Model):
    image = models.FileField(upload_to=get_upload_file_name, default="") 
    action = models.ForeignKey(Action)

def get_upload_file_name(instance, filename):
    return "uploaded_files/%s_%s" % (str(datetime.now().day).replace('.','_'), filename)

表格:

class ActionForm(ModelForm):
    #bind form to Action model
    class Meta:
        model = Action
        fields = ['name','keywords', 'object', 'UploadedBy', 'uploadDate']

class ImageForm(ModelForm):
    class Meta:
        model= Image
        fields =['image']

在视图中创建表单的代码:

def actioncreate(request):
    if request.method == "GET":
        #create the object - Actionform 
        form = ActionForm;
        form2 = ImageForm;
        #pass into it 
        return render(request,'app/createForm.html',  'form':form, 'form2':form2)
    elif request.method == "POST":
        # take all of the user data entered to create a new action instance in the table
        form = ActionForm(request.POST, request.FILES)
        form2 = ImageForm(request.POST, request.FILES)
        if  form.is_valid() and form2.is_valid():
            act = form.save(commit=False)
            img = form2.save(commit=False)
            #set the action_id Foreignkey 
            act.id = img.action_id                 
            act.save()
            img.save()
            return HttpResponseRedirect('/actions')
        else:
            form = ActionForm()
            form2 = ImageForm;
            return render(request,'app/createForm.html',  'form':form, 'form2':form2 )

表单创建良好,但提交时,它会尝试保存 image.id、image.image(文件名)并为 image.action_id 返回 null 我收到错误:

null value in column "action_id" violates not-null constraint
DETAIL:  Failing row contains (2, uploaded_files/29_personrunning_Hq8IAQi.jpg, null).   

我显然需要用 django 在提交第一部分“表单”时创建的 action.id 填充第三列。有没有一种方法可以获取 action.id 值并在一个表单提交中填充图像表中的 action_id 字段? image.action_id 最初被声明为与模型中的操作相关的外键。

【问题讨论】:

【参考方案1】:

第一个问题与act = form.save(commit=False)有关,因为它会返回一个尚未保存到数据库的对象,然后act没有ID。您需要先保存(并提交)act

以下行中还有另一个错误:

act.id = img.action_id  # It should be: img.action_id = act.id

您可能希望将act 分配给img.action。请注意,您以错误的方式执行此操作(您将img.action 分配给act)。最好的方法是:

img.action = act  # This is equivalent to img.action_id = act.id

尝试交换这些行:

        act.save()
        img.action = act

【讨论】:

以上是关于一起提交 2 个表单,将其中一个的主键作为外键传递给另一个的主要内容,如果未能解决你的问题,请参考以下文章

如何将房间自动生成的主键作为外键添加到另一个实体

关于 主键和外键

为啥我需要将子表的主键作为父表的外键,而不是相反的 1:1 识别关系?

数据库中的主键和外键

使用 SQL 和 C# 将表 1 的主键分配为表 2 中的外键

外键(FK_ 必须与引用的主键具有相同的列数