1

I have a url /<subject_id>/comments/new/ which renders a Django ModelForm. I am using a view class derived from FormView to process the form. I wish to do the following:

  1. subject_id should not appear on the rendered form.
  2. subject_id should be added to the form prior to is_valid() being called, or if this is not possible should be added to the Comment instance.

forms/comment_form.py:

class CommentForm(ModelForm):
    class Meta:
        model = Comment
        fields = ['text']

views.py:

class CommentCreate(FormView):
    form_class = CommentForm

    def form_valid(self, form):
        # Do some stuff to the validated Comment instance
        # Maybe save the comment, maybe not
        return super().form_valid(form)

How do I do this? If I add subject_id as a field in CommentForm then it appears on the rendered form. If I don't then the form is instantiated with subject_id present from `self.kwargs['subject_id'] and complains of an "unexpected keyword argument".

1
  • what is your model ? Commented Jun 17, 2018 at 12:12

2 Answers 2

2

After some hunting around in the docs I have discovered that the correct answer is to use the get_form() method to pre-populate the form with the data that I don't want to appear on the form, but that needs to be present for validation.

class CommentCreate(FormView):
    form_class = CommentForm

    def get_form(self):
        self.subject= get_object_or_404(Subject, id=self.kwargs['subject_id'])
        partial_comment = Comment(user=self.request.user, subject=self.subject)
        form = CommentForm(**self.get_form_kwargs(), instance=partial_comment)
        return form
Sign up to request clarification or add additional context in comments.

1 Comment

The line form = CommentForm(**self.get_form_kwargs(), instance=partial_comment) can cause problems by redeclaring instance. You may need to update **self.get_form_kwargs() instead of adding it to the instantiation of the form.
1

You can remove subject_id from form fields:

class CommentForm(ModelForm):
    class Meta:
        model = Comment
        fields = ['text']

And add it to new comment object in form_valid method like this:

class OrderCreate(FormView):
    form_class = CommentForm

    def form_valid(self, form):
        subject_id = self.kwargs['subject_id']
        subject = Subject.objects.get(id=subject_id)  
        form.instance.subject_id = subject
        return super().form_valid(form)

4 Comments

Unfortunately this does not work. I get the error: 'CommentForm' has no field named 'subject'.
@Tintin this code shouldn't raise the error. Problem is somewhere else. Can you post template and full traceback?
The error is being throw by the Comment.clean() which references Subject. I need to populate the form data with subject_id before is_valid() is called.
@Tintin ok, can you post full traceback and template also?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.