简体   繁体   中英

Django Form initial Value For Foreignkey Field

I have two django models which are:

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)

When saving a Source, I would like to initiate the value of the corresponding Dataset. I tried to initiate the value of my form as suggested here: 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)

The SourceForm:


class SourceForm(ModelForm):

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

The suggested way does not work. I was able to achieve the desired result by adding the commented line above. It is not a recommended solution since it makes a second call to the database.

Any idea how to give properly the dataset object to the source?

Passing values in initial for excluded fields does not do anything. Instead what you can do is modify the instance wrapped by the form before saving the it:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM