1👍
If I understood correctly, you’d like to attach the Foo instance to Bar,
based on user’s input for the field a, and to automatically create a Foo instance
if one doesn’t already exist.
With these models:
class Foo(model.Model):
a = model.CharField()
class Bar(model.Model):
b = model.ForeignKey(Foo)
... more fields here
in your ModelForm you can do this:
class BarForm(forms.ModelForm):
class Meta:
model = Bar
fields = [other fields from the Bar model, ...]
foo_a = forms.CharField(...)
foo_instance = None # for clarity/documentation only
def clean_foo_a(self):
value = self.cleaned_data['foo_a']
self.foo_instance = Foo.objects.get_or_create(a=value)
return value
def save(self, *args, **kwargs):
"""
Attach Foo to the newly created Bar instance.
The code below takes into account the standard "commit" kwarg for ModelForm's
"""
commit = kwargs.pop('commit', True)
bar_instance = super(BarForm, self).save(commit=False, *args, **kwargs)
bar_instance.b = self.foo_instance
if commit:
bar_instance.save()
return bar_instance
The idea is to add another field – foo_a – that we’ll use to lookup/create the Foo instance.
Other possibilities include custom widgets that do this for you, custom form fields, etc.,
but it all depends on how often will you use this pattern in your app.
Source:stackexchange.com