Django 表单外键字段的初始值

时间:2021-04-24 17:03:45

标签: python django

我有两个 django 模型,它们是:

class Dataset(models.Model):
    name = models.CharField(max_length = 200)
    description = models.CharField(max_length=1000)
    owner = models.ForeignKey(Profile, null=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


class Source(models.Model):
    name = models.CharField(max_length = 200)
    description = models.CharField(max_length=1000)
    dataset = models.ForeignKey(Dataset, null=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

当保存一个Source时,我想初始化对应Dataset的值。我尝试按照此处的建议启动表单的值:foreign key as initial value not passed to the ModelForm in django

def create_source(request, dataset_id):

    user = request.user
    dataset = Dataset.objects.get(id=dataset_id)

    form = SourceForm(initial={"dataset" : dataset, })

    if request.method == "POST":
        form = SourceForm(request.POST or None, initial={"dataset" : dataset, })
        if form.is_valid():
            source = form.save()
            # dataset.source_set.add(source) # Only works if I add this line
            return redirect("source", dataset_id=dataset_id, source_id=source.id)

    context = {"form": form}
    return render(request, "sources/source_form.html", context)

源表单:


class SourceForm(ModelForm):

    class Meta:
        model = Source
        fields = "__all__"
        exclude = ["dataset"]

建议的方式不起作用。通过添加上面的注释行,我能够达到预期的结果。这不是推荐的解决方案,因为它会再次调用数据库。

知道如何将数据集对象正确地提供给源吗?

1 个答案:

答案 0 :(得分:1)

为排除的字段传递初始值不会做任何事情。相反,您可以做的是在保存表单之前修改表单包装的实例:

def create_source(request, dataset_id):

    user = request.user
    dataset = Dataset.objects.get(id=dataset_id)

    form = SourceForm() # No initial

    if request.method == "POST":
        form = SourceForm(request.POST) # this is a submitted form `request.POST or None` makes no sense use only `request.POST`
        if form.is_valid():
            form.instance.dataset = dataset
            source = form.save()
            return redirect("source", dataset_id=dataset_id, source_id=source.id)

    context = {"form": form}
    return render(request, "sources/source_form.html", context)