How to pass hidden default value for a new entry?

Hi,
my question is a general one and I’m using the Author - Book example from the Django Tutorial: The Local Library website https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website

The model structure can be found here: https://github.com/mdn/django-locallibrary-tutorial/blob/master/catalog/models.py

class Author(models.Model):
“”“Model representing an author.”""
first_name = models.CharField(max_length=100)

class Book(models.Model):
“”“Model representing a book (but not a specific copy of a book).”""
title = models.CharField(max_length=200)
author = models.ForeignKey(‘Author’, on_delete=models.SET_NULL, null=True)

My views.py:
def book_new(request):
if request.method == “POST”:
form = BookForm(request.POST)
if form.is_valid():
book = form.save(commit=False)
book.save()
return redirect(‘author-detail’, pk=book.author.id)
else:
form = BookForm()
return render(request, ‘catalog/book_form.html’, {‘form’: form})

The Book template:

My forms.py (this works but has the author visible)
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = (‘title’, ‘author’, ‘summary’, ‘isbn’, ‘genre’, ‘language’,)

If I remove the author:
fields = (‘title’, ‘summary’, ‘isbn’, ‘genre’, ‘language’,)
then I get an error when the template is populated ‘NoneType’ object has no attribute ‘id’ which of course is because I do not list the author for the form.

The question:
The Author form shows the basic info of the Author and below it lists the Books written by the Author. In the author template, I have added an “Add” button for creating a new book written by the Author: Add

How can I pass the author.id to the Book template so that the Author field is hidden and prefilled with the author.id?

I have read something about Widgets in the forms but do not know how to pass the hidden default value to the Book template and if I need to edit the template too in order to make the Author hidden.

Thank you for your help,
-Kari

Hello!

You can hide this field on the form. You should put it in forms.py between class BookForm(forms.ModelForm) and class Meta:.

author = forms.CharField(widget = forms.HiddenInput(), required = False)
1 Like

Hi Mihail,

thank you for your reply. I edited the forms.py as you instructed.
When I now open a new entry for a book from the Author form the author field is hidden as expected. When I save the new Book, I get the following error:
Cannot assign “’’”: “Book.author” must be a “Author” instance.

Request information
USER someuser
GET No GET data
POST
Variable Value
csrfmiddlewaretoken ‘somevalue’
title ‘The Title’
summary ‘Summary of Book’
isbn ‘978-3-16-1484’
genre ‘2’
language ‘1’
author ‘’

It seems that I still need to pass the author.id to the Book template so that the Author field is prefilled with the author.id (the hidden field).

So I need to pass the author.id from the Author form in the url, something like http://127.0.0.1:8000/catalog/book/new?author=123 and then in the Book form or template put that value into the author.id.

The thing is that I do not know how to do that. As shown above, the book_form.html template builds the form using {{ form.as_table }}, so there seems to be no way to read the author.id from the url. Is there a way to set it in the forms.py as a default value? Something like:
author = forms.CharField(widget = forms.HiddenInput(), required = False, default = url.author)?

-Kari