1

I've created a form which by submit uploads an item to the database. The problem is that if I press f5 it'll submit the form again, because of the URL is now different.

I have these two url patterns

urlpatterns = [
            url(r'(?i)^CMS/$', views.CMS, name='CMS'),

            url(r'^createItem/$', views.createItem, name='createItem')
]

and my view looks like this

def CMS(request):       
    form = itemCreateForm()

    context = {
          'form' : form,
          'message' : 'Content Manage Site'
    }
    return render(request, 'CMS.html', context)

def createItem(request):       
    f = itemCreateForm(request.POST)

    if f.is_valid():
        f.save()
        pass

    form = itemCreateForm()

    context = {
          'form' : form,
          'message' : 'ItemCreated!'
    }

    return render(request, 'CMS.html', context)

the CMS.html

{% if message %}
    {{ message }}
{% endif %}

<div class='newItemFields'>
    <form action="{% url 'kar:createItem' %}" method="POST">
    {% csrf_token %}
        {{ form.as_p }}
        <input type="submit">
    </form>
</div>

my form

class itemCreateForm(ModelForm):
    class Meta:
        model = item 
        fields = ['name', 'type', 'price']

I start at homepage/CMS/ and fill in the form and press submit, and view function createItem runs and creates and saves the object in the database. And sends the user to homepage/CMS/createItem. And now everytime the user press f5 the createItem function will run again and insert another object into the database with the same values as the previous one, even though the input fields are empty (can't wrap my head around that).

I also twice write form = itemCreateForm() which I believe is dubious?

What I'd like to do is after createItem is run, it should send the user back to homepage/CMS/ and not homepage/CMS/createItem. Would that be the proper way to do it? Or is there a smart way of doing this.

1
  • Is this sorted out now? Commented Dec 28, 2016 at 8:51

2 Answers 2

1

At the end of your createItem function, you are rendering HTML of the page rather than redirecting. Instead, you need to do

return HttpResponseRedirect(reverse('kar:index'))

You will need to import HttpResponseRedirect and reverse which is used to resolve the URL through its name.

Check this out: https://docs.djangoproject.com/en/1.10/topics/forms/#the-view

Sign up to request clarification or add additional context in comments.

1 Comment

Tried this and it gave me a django.core.urlresolvers.NoReverseMatch: Reverse for 'index' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['Homepage/(?i)^$']
1

What I'd like to do is after createItem is run, it should send the user back to homepage/CMS/ and not homepage/CMS/createItem. Would that be the proper way to do it? Or is there a smart way of doing this.

That would indeed be the proper and smart way to do it. Have one view handle both GET and POST and then redirect after successful form submission. This ensures that the user can't resubmit the form merely by refreshing. And you address your concern about repeating your code.

urlpatterns = [
    url(r'(?i)^$', views.index, name='index'),
    url(r'^createItem/$', views.createItem, name='createItem')
]

Then combine your views

def createItem(request):       
    if request.method == 'POST':
         f = itemCreateForm(request.POST)

         if f.is_valid():
             f.save()
             return HttpResponseRedirect('/homepage/CMS/')
    else :
         form = itemCreateForm()

         context = {
              'form' : form,
              'message' : 'Content Manage Site'
         }
    return render(request, 'CMS.html', context)

Note that the code is now shorter, it gives proper feedback to the user when the form is not valid. And you can't refresh to submit the for twice. We need a small change to the template

<div class='newItemFields'>
    <form action=method="POST">
    {% csrf_token %}
        {{ form.as_p }}
        <input type="submit">
    </form>
</div>

The message display part isn't needed anymore

2 Comments

Terrible sorry I wrote the wrong url in my url patterns. Should not have been the one with index, but my CMS. Does this change anything though?
no worries. It doesn't make a big change. YOu can change urls.py whenever you like and you can make sure your redirect doesn't break by making using the reverse function (after asigning a name to the url)

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.