Reputation: 2688
During form processing I'd like to be able to set a foreign key field on a model object without the user having to select the key from a dropdown.
For instance:
#models.py
class AAA(models.Model):
some_field = models.TextField()
class BBB(models.Model):
another_field = models.TextField()
key_field = models.ForeignKey('AAA')
The user will navigate from a view showing an instance of 'AAA' to a create_object style view that will create an instance of 'BBB' given a parameter referring to 'AAA'. The foreign key is set in code to point back to the 'AAA' instance.
The django comments framework seems to do this but I can't figure out how.
Any ideas? I'm sure it should be quite simple.
Upvotes: 5
Views: 12062
Reputation: 308899
You can exclude the key_field
from your model form, save with commit=False
, then set key_field
in your view before saving to the database.
class BBBForm(forms.ModelForm):
class Meta:
model = BBB
exclude = ("key_field",)
def create_view(request, **kwargs):
if request.method == "POST":
aaa = # get aaa from url, session or somewhere else
form = BBBForm(request.POST)
if form.is_valid():
bbb = form.save(commit=False)
bbb.key_field = aaa
bbb.save()
return HttpResponseRedirect("/success-url/")
...
Upvotes: 31
Reputation: 5570
As the user creates a BBB
via an instance of AAA
, this should be reflected in the URL, i.e., your "create_object style view" will get a parameter identifying an AAA
object. You can use it to get the object from the database and create your BBB
object accordingly:
from django.shortcuts import get_object_or_404
def create_bbb_view(request, aaa_id):
a = get_object_or_404(AAA, id=aaa_id)
form = MyBBBCreationForm(request.POST) # or similar code
if form.is_valid():
b = BBB.objects.create(key_field=a) # plus other data from form
# ...
(You could also set key_field
to aaa_id
directly, but it's probably a good idea to check if the object exists.)
Upvotes: 4