user6536435
user6536435

Reputation:

Restricting Access to Django's success_url()

New Django user here. I am trying to restrict access to Django's success_url() upon GET requests. I realize I am not the first to ask this question, however, I am specifically trying to achieve this in conjunction with Django's generic class-based views. Generic views seem cleaner, faster, and more idiomatic. I want to use them as much as possible unless they are absolutely unfit for the job.

Basically, I am creating a simple contact form for non-users who only want to send me a message without creating an account. I've created a contact app to handle these types of contacts. I've created a ModelForm, which I am rendering with a contact.html with Django's FormView. After a person submits the form, they will receive a cool looking thank you message, rendered with a thanks.html, which has its own url.

But I only want them to see the thank you message if they POST the contact form. Currently, you can go on my site and type '/contact/thanks/', and my thanks.html will be rendered whether you've submitted a form or not. Django's success_url apparently defaults to a GET request.

Here's my view:

class MyContact(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = 'thanks'

Here's my form:

ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        fields = ['email_address', 'message_body']

Here's the html form in contact.html:

    <form action="" method="POST">{% csrf_token %}
    {{ form|crispy }}
    <button type="submit" class="send btn btn-secondary">Send Message</button>
    </form>

My first thought was to decorate my contact app url with a require_POST() decorator like this:

urlpatterns = [
url(r'^thanks/$', require_POST(views.ThanksPageView.as_view()), name='thanks'),

]

This doesn't work because Django's success_url() defaults to a GET request.

What is the most idiomatic way to approach this? Since Django is a 'batteries included' framework, I do not want to use 'duck-tape', meaning I do not want implement any ad-hoc logic in my views or urls.

Sorry if I've missed anything in the docs or questions archive.

Upvotes: 0

Views: 188

Answers (1)

mhkuu
mhkuu

Reputation: 91

Since you're asking for a idiomatic approach, I would consider the messages framework and specifically the SuccessMessageMixin. This would allow you to add a success message to e.g. the contact form itself and the url-pattern for the /thanks/ page would not be necessary.

Upvotes: 2

Related Questions