How to subclass django-contact-form to create custom contact form?

70 views
Skip to first unread message

Tobias Dacoir

unread,
Jan 19, 2015, 5:13:34 AM1/19/15
to django...@googlegroups.com
I need to include two different contact forms in my app. One a general contact form and another Report / Feedback form that pre-fills some data depending on which site it was called from.
So I hit google, found django-contact-form, installed it and after creating some basic templates (and rest of the configuration) I was able to make use of /contact/ to present a basic form which takes in Name, Email and Message. Works fine.

Now I need that Report Form. The idea is to have a 'Report' Button on the Website which maps to /report/$Parameter (or maybe it will just put the parameter into request, not sure yet how to do this).
However I have troubles getting my Custom Form to work. I tried to create a new view that uses my custom form which just inherits from ContactForm:

forms.py:
class ReportForm(ContactForm):
    additional
= forms.CharField(max_length=100, label='additional field test')
    subject_template_name
= "contact_form/report_form_subject.txt"
    template_name
= 'contact_form/report_form.txt'



views.py:
def report(request):
    reportForm
= ReportForm
   
return render(request, 'play/report.html', {'form': reportForm})




template report.html:
{% extends 'base.html' %}

{% block body_block %}
<h2>Report Form</h2>
  <p>To send us a message fill out the below form.</
p>
 
<form method="post">{% csrf_token %}
   
<p>Name: <input type="text" name="name"></p>
   
<p>Your e-mail: <input type="text" name="email"></p>
     
<p>additional field test: <input type="text" name="additional"</p>
    <p>Message: <textarea name="body" rows="10" cols="50"></
textarea></p>
   
<input type="submit" value="Submit">
 
</form>
{% endblock %}

However it's not working at all. I can see the form displayed thanks to the HTML Template, but nothing is happening when I press Submit. There is no example on the website on how to subclass it :(
http://django-contact-form.readthedocs.org/en/latest/quickstart.html
Or should I just copy and paste the whole code from here and adapt it to include additional fields: https://bitbucket.org/ubernostrum/django-contact-form/src/4b7d2fa20c1d01568fb7c4c800155378e176923b/contact_form/forms.py?at=default



AJ

unread,
Jan 19, 2015, 5:57:02 AM1/19/15
to django...@googlegroups.com
Hi,

What i understood is that you need two different forms on single page. and later on you want to map feedback form as site specific.

So you can do with two different ways:

1) define two different form action path.

<form id="login_form" action="{% url app.views.contactus %}" method="post">

   ...form fields...

</form>

<form id="registration_form" action="{% url app.views.feedback %}" method="post">

   ...form fields...

</form>


2) you have will have to provide two different buttons in template say 

<input type="submit" value="Submit" name="contactus">
<input type="submit" value="Feedback" name="feedback">


And write view for it, which will identify response method 

This view is only for saving contact us

if request.method == 'POST' && 'contactus' in request.post :
    contactform = contactForm(request.POST)
    if contactform.is_valid():
        contactform.save()
elif  request.method == 'POST' && 'feedback' in request.post :
       feedbackform = feedbackForm(request.POST)
    if feedbackform.is_valid():
        feedbackform.save()
else:
    contactform = contactForm()
    feedbackform = feedbackform()

Thanks,
Aj

Vijay Khemlani

unread,
Jan 19, 2015, 6:49:56 AM1/19/15
to django...@googlegroups.com
Right now the "reportForm" variable is pointing to the RequestForm class, not to an object, so you need to do it like this

reportForm = ReportForm()    # Take note of the parenthesis

In your template, your form tag need an action attribute (well, it's not mandatory but it is highly advised). In this case if you want the same view to process your form you just need to use ".".

<form method="post" action="." ... >

With those changes you should be able to render the form as usual:

{{ form.as_p }}

Also I'm not sure what do you mean when you say thet nothing is happening when you pres the Submit button. As you have it right now it just calls the same view ("report") that you wrote. Since the view does not have different rules for GET and POST requests it just renders the same page again.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/e72e813c-d78b-433f-8444-e76a4129c862%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted
Message has been deleted

Tobias Dacoir

unread,
Jan 19, 2015, 7:13:16 AM1/19/15
to django...@googlegroups.com
Thanks for the reply. I was wondering about the if statement about request.type as well, but I took the code from Stackoverflow and a combination of the original source code. It calls a Class.as_view() and I wasn't sure if I need to overwrite that as well. I didn't really want to write all the view code logic again as it kinda defeats the purpose of having a 3rd party app that does that for me.

According to the official documentation I'm still unsure if I need to type anything in my views.py at all.
As far as I understand this, I just need to subclass ContactForm somehow:

class ContactForm(forms.Form):
    """
    The base contact form class from which all contact form classes
    should inherit.

    If you don't need any custom functionality, you can simply use
    this form to provide basic contact functionality; it will collect
    name, email address and message.

    The ``ContactForm`` view included in this application knows how to
    work with this form and can handle many types of subclasses as
    well (see below for a discussion of the important points), so in
    many cases it will be all that you need. If you'd like to use this
    form or a subclass of it from one of your own views, just do the
    following:

    1. When you instantiate the form, pass the current ``HttpRequest``
       object to the constructor as the keyword argument ``request``;
       this is used internally by the base implementation, and also
       made available so that subclasses can add functionality which
       relies on inspecting the request.

    2. To send the message, call the form's ``save`` method, which
       accepts the keyword argument ``fail_silently`` and defaults it
       to ``False``. This argument is passed directly to
       ``send_mail``, and allows you to suppress or raise exceptions
       as needed for debugging. The ``save`` method has no return
       value.

    Other than that, treat it like any other form; validity checks and
    validated data are handled normally, through the ``is_valid``
    method and the ``cleaned_data`` dictionary.

taken from here: https://bitbucket.org/ubernostrum/django-contact-form/src/4b7d2fa20c1d01568fb7c4c800155378e176923b/contact_form/forms.py?at=default

Vijay Khemlani

unread,
Jan 19, 2015, 7:21:20 AM1/19/15
to django...@googlegroups.com
OK, I read a little of the library documentation, and this is what you have to do I think

1. subclass the ContactForm (you already have that)
2. subclass the ContactFormView from the library, at least with this:

class ReportFormView(ContactFormView):
    form_class = ReportForm

3. Map this view to a path in yout urls.py

url(r'report/$', ReportFormView.as_view())

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.

Tobias Dacoir

unread,
Jan 19, 2015, 7:24:24 AM1/19/15
to django...@googlegroups.com
I managed to do it! Thanks to your help.

Ok all you need to do is this:

views.py:
class ReportFormView(FormView):
    form_class
= ReportForm
    template_name
= 'contact_form/contact_form.html'

   
def form_valid(self, form):
        form
.save()
       
return super(ReportFormView, self).form_valid(form)

   
def get_form_kwargs(self):
       
# ContactForm instances require instantiation with an
       
# HttpRequest.
        kwargs
= super(ReportFormView, self).get_form_kwargs()
        kwargs
.update({'request': self.request})
       
return kwargs

   
def get_success_url(self):
       
# This is in a method instead of the success_url attribute
       
# because doing it as an attribute would involve a
       
# module-level call to reverse(), creating a circular
       
# dependency between the URLConf (which imports this module)
       
# and this module (which would need to access the URLConf to
       
# make the reverse() call).
       
return reverse('contact_form_sent')



Add this to URL patterns:
  url(r'^report/', ReportFormView.as_view(), name='report_form'),



and in forms.py subclass like this:

class ReportForm(ContactForm):
    additional
= forms.CharField(max_length=100, label='additional field test')
    subject_template_name
= "contact_form/report_form_subject.txt"
    template_name
= 'contact_form/report_form.txt'

And the template, thanks to you is easy as pie:
report.html:
{% extends 'base.html' %}

{% block body_block %}
<h2>Contact Form</h2>

  <p>To send us a message fill out the below form.</
p>

       
<form method="post">{% csrf_token %}
{{ form.as_p }}

           
<input type="submit" value="Submit">
 
</form>
{% endblock %}



Now I just need to figure out how to pre-fill.

Reply all
Reply to author
Forward
0 new messages