1

I have the following models—

class Book(Model):
 title = CharField(max_length=100)
 author = ForeignKey('Author')

class Author(models.Model):
 name = CharField(max_length=100)

And have a standard ModelForm to Book.

In the form, author is a ModelChoiceField, and is rendered as a <select>. I'd like it to be text field where you can input the author's name—Author.name.

If there's already an author with that name, the saved model uses that in its foreign key, otherwise an author with that name is created (and used in its foreign key)—in effect, Author.get_or_create(name=posted_name_value).

I've found that the simplest way is to override the field as a CharField, like so—

class BookForm(ModelForm):

 author = CharField()

 class Meta:
  model = Book

Although with that I can add custom clean logic that does what I want, I can't do the same with the pre-populated value when using BookForm(instance=some_book_object)—the CharField gets set to the Author's pk, not its name.

I've tried to do this but I can't seem to find out how. I've tried overriding things in BookForm.__init__ to no avail.

How can I override a fields' value set when using instance with a ModelForm?

user1569050
  • 6,099
  • 2
  • 18
  • 14

2 Answers2

0

You could override the field content by this:

form = BookForm(instance=instance, initial={'name': instance.author.name})
Wolkenarchitekt
  • 20,170
  • 29
  • 111
  • 174
Raunak Agarwal
  • 7,117
  • 6
  • 38
  • 62
0

I'd add author to the ModelForm meta's exclude, then have a form field called author_name that you populate using initial, and save into the model in the view's form_valid method (assuming you are using generic form view classes).

AKX
  • 152,115
  • 15
  • 115
  • 172