I want to use a form to generate a new object (say a Book) from a Person's page such that the new Book is automatically associated with that Person via a foreign key, but I am running into trouble getting the Person correctly associated and saved with the form. For my models, I have:
class Person(models.Model):
p_id = models.PositiveIntegerField(primary_key=True, unique=True)
class Book(models.Model):
person = models.ForeignKey(Person)
title = models.CharField(max_length=100)
I then have a custom form to create a Book:
class AddBookForm(forms.ModelForm):
class Meta:
model = Book
fields = ('title', 'person',)
widgets = {
'person': forms.HiddenInput,
}
And a view to create the Book (which is also given the pk
(p_id
) of the Person):
class AddBook(CreateView):
model = Book
I have tried various things to get this to work:
get_initial
, but this disappears for some reason with the input is set to hidden (frustratingly).form_valid
method in the view, but this only occurs after the form has already been validated, so I need to add Person before that.clean_person
method in the form class, but that only occurs after the form has been validated by the clean
method.Currently, I am trying to override the clean
method. However, I don't know how to get the Person at this point, after the form has already been sent for cleaning. In the view, I could access it with Patient.objects.get(p_id=self.kwargs.get('pk'))
.
Is there some way I can add the data to the form in my view (as a class-based view) that it won't get stripped away OR is there some way I can access the Person or p_id
foreign key at this point to add the data in the clean
method?
You're going at it the wrong way: the person is not user input, so this information should not reside in the form. You can override the form_valid
method as follows:
class AddBook(CreateView):
model = Book
def form_valid(self, form):
form.instance.person_id = self.kwargs.get('pk')
return super(AddBook, self).form_valid(form)
This will set the person_id
attribute on the instance used by the form to save the data, and then call the super
method to save that instance and return a redirect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With