Class-based FormView Contact Form

191 views
Skip to first unread message

Paul Walsh

unread,
Sep 1, 2011, 5:32:19 AM9/1/11
to django...@googlegroups.com
I want to make a contact form using the class-based FormView. How do I pass the recipient email?

Let's say I want a pre-defined recipient, and also the option for the sender of the form to receive a copy.

I can do this with a function view but I'd like to use the new class-based generic views.

Paul Walsh

unread,
Sep 5, 2011, 6:17:18 AM9/5/11
to django...@googlegroups.com
Anyone?

I really want to use class-based views, but it is hard with so much missing in terms of examples/tutorials.

thx.

Russell Keith-Magee

unread,
Sep 5, 2011, 10:32:23 AM9/5/11
to django...@googlegroups.com

Hi Paul,

First off, apologies for the current state of the Class-based views
documentation. It's one of the known weak points in the documentation
at the moment, and something that I'd really like to rectify.

Secondly, to address your actual question -- it depends on exactly
what you want to do.

If you're just looking to pass in an extra argument to the Form
instance when it is constructed in an UpdateView or CreateView, then
you should be looking to the extension points in the FormMixin class -
in particular, get_form() (which constructs the form instance), and/or
get_form_kwargs(), which returns the arguments that will be passed to
construct the form. So, if you just want to add a "recipient=foo"
argument to the form constructor, override get_form_kwargs(), and add
the extra argument to the dictionary constructed by the parent, and
return the result:

class MyView(UpdateView)
...
def get_form_kwargs()
kwargs = super(MyFormClass, self).get_form_kwargs()
kwargs.update({'recipient': ... })
return kwargs

An alternative is to take a different look at the way you're using the
form. If the recipient isn't actually necessary for form processing
itself (i.e., it's just there as a required default value for a model
instance), then don't pass it to the form at all. Instead, set the
value for recipient on the instance, and just don't save that change.
In a normal function based view, this is the equivalent of something
like:

instance = Thing.objects.get(...)
instance.recipient = 'f...@example.com'
if request.method == 'POST':
form = MyThingForm(instance=instance, data=request.POST)

This means that the instance used by the form is saveable -- because
it has a valid value for recipient -- but it doesn't require any
custom arguments to the instance itself.

To do this in a class-based view, look to the get_object() method on
the SingleObjectMixin. This is the method that is used to retrieve the
instance that will be manipulated; if you override get_object() and
add the extra recipient argument, then whenever a view needs an object
instance, it will be given one with a pre-set recipient value.

As a last resort -- I would actually suggest digging into the CBV
source code a bit. It may seem daunting to do this, but the CBV code
is quite well documented code, and although there are a lot of
methods, most of them are fairly simple internally. I know this isn't
a good substitute for having adequate documentation, but it may be
better than nothing.

Hope that helps!

Yours,
Russ Magee %-)

Paul Walsh

unread,
Sep 12, 2011, 4:36:30 PM9/12/11
to django...@googlegroups.com
Hi Russ,

Thanks for the input. I am actually looking to use FormView as opposed to UpdateView or CreateView because I am not working with model data at all: I want to create a simple contact form, and send the data of the form to a recipient via email - I don't want to write anything to the db at all. I am pretty new to Django so maybe this is obvious to some. Anyway, the way I understand your answer it is basically to do with model data. 

I'll dig into the source code.

thx
Reply all
Reply to author
Forward
0 new messages