Reputation: 372
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 ?
Upvotes: 1
Views: 710
Reputation: 21797
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)
Upvotes: 1