cer
cer

Reputation: 2005

Page not found (404 error) on Django HttpResponseRedirect

I see that there are numerous posts related to HttpResponseRedirect errors(Django form redirect using HttpResponseRedirect, Django: HttpResponseRedirect not working, How can I redirect to a Thank you for contacting us page after user submits a form with Django?), and the explanations all make sense. Unfortunately, they have not helped me address my problem -- which I think/hope is more about looking at this too long and I can no longer see the forest for the trees.

I am working off of this example (https://techwithtim.net/tutorials/django/simple-forms/). I have a couple of models that have been incorporated into forms.py, views.py, and urls.py but the redirect is not functioning as expected.

The short of it is that I have two forms, when the first form is correctly submitted, it should got to the next form (url). Once that is correctly submitted, it should go to a thank you page.

The first form is displayed at http://localhost:8000/packages/new_developer/ and should go to http://localhost:8000/packages/add_package/', but is going to http://localhost:8000/add_package/' instead. Although the information is being captured and placed in the db, I have been unsuccessful at getting a redirect. I have tried changing/removing slashes as well as moving files to different locations -- all to no avail.

Here is the actual error:

Page not found (404)
Request Method:     GET
Request URL:    http://localhost:8000/add_package/

Using the URLconf defined in Bio.urls, Django tried these URL patterns, in this order:

    admin/
    packages/
    accounts/
    ^static/(?P<path>.*)$

The current path, add_package/, didn't match any of these.

You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

excepts from forms.py

class NewDeveloper(forms.Form):
   first_name = forms.CharField(label='First Name', max_length=100)
   last_name = forms.CharField(label='Last Name', max_length=100)

   email = forms.EmailField(label='Email')

   department = forms.CharField(max_length=100)
   institution = forms.CharField(max_length=100)

   city = forms.CharField(max_length=100)
   state = forms.CharField(max_length=100)

   comments = forms.CharField(required=False, widget=forms.Textarea)
       
   class Meta:
      model = Developer
      fields = ('last_name', 'first_name', 'email', 'institution', 'department', 'city', 'state')
   
      return {'first_name': first_name, 'last_name': last_name, 'email':email, 'department':department, 'institution':institution, 'city':city, 'state':state, 'subject':subject, 'comments':comments}

class NewTool(forms.Form):
   tool_name = forms.CharField(max_length=50)
   release_date = forms.DateField(label='Release Date')
   github_repo = forms.URLField(max_length=100)
   summary = forms.CharField(widget=forms.Textarea)
   category = forms.CharField(max_length=500)
   developer = forms.CharField(max_length=200)

   class Meta:
      model = Tool
      fields = ('tool_name', 'release_date', 'github_repo', 'summary', 'developer', 'category')   

excepts from views.py

from django.http import FileResponse, Http404, HttpResponseRedirect
...
from .models import Tool, Developer, ToolInstance, Category, Publication
from packages.forms import NewDeveloper, NewTool

def new_tool(request):
   if request.method == 'POST':
      form = NewTool(request.POST)

      if form.is_valid():
         query = Tool.objects.filter(tool_name=form.cleaned_data['tool_name']).count()

         if query == 0:
            tool = Tool()
            tool.tool_name = form.cleaned_data['tool_name']
            tool.release_date = form.cleaned_data['release_date']
            tool.github_repo = form.cleaned_data['github_repo']
            tool.developer = form.cleaned_data['developer']
            tool.summary = form.cleaned_data['summary']
            tool.category = form.cleaned_data['category']
            tool.save()

         return HttpResponseRedirect('/thanks/')

   else:
      form = NewTool()

   return render(request, 'add_package.html', {'form':form})


def new_developer(request):
   if request.method == 'POST':
      form = NewDeveloper(request.POST)

      if form.is_valid():
         query = Developer.objects.filter(first_name=form.cleaned_data['first_name'], last_name=form.cleaned_data['last_name']).count()

         if query == 0:
            developer = Developer()
            developer.first_name = form.cleaned_data['first_name']
            developer.last_name = form.cleaned_data['last_name']

            developer.email = form.cleaned_data['email']
            developer.department = form.cleaned_data['department']
            developer.institution = form.cleaned_data['institution']
            developer.city = form.cleaned_data['city']
            developer.state = form.cleaned_data['state']

            developer.comments = form.cleaned_data['comments']

            developer.save()

      return HttpResponseRedirect('/add_package/')

   else:
      form = NewDeveloper()

   return render(request, 'new_developer.html', {'form':form})

def thanks(request):
    message = 'Thank you for your submission!'
    context = {'message': message,}
 
    return render(request, 'thanks.html', context=context)

excepts from urls.py

from django.conf.urls import url 
from . import views

urlpatterns = [ 
   path('', views.index, name='index'),
   path('tools/', views.ToolListView.as_view(), name='tools'),
   path('tool/<int:pk>', views.ToolDetailView.as_view(), name='tool-detail'),
   path('developers/', views.DeveloperListView.as_view(), name='developers'),
   path('developer/<int:pk>', views.DeveloperDetailView.as_view(), name='developer-detail'),   path('publications/', views.PublicationListView.as_view(), name='publications'),
   path('publication/<int:pk>', views.PublicationDetailView.as_view(), name='publication-detail'), 
   path('new_developer/', views.new_developer, name='new_developer'),
   path('new_tool/', views.new_tool, name='new_tool'),
   path('thanks/', views.thanks, name='thanks'),
]

and here is my file structure (I have left off some files/folders for compactness):

├── Bio 
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── db.sqlite3
├── manage.py
├── packages
│   ├── admin.py
│   ├── apps.py
│   ├── contact.py
│   ├── forms.py
│   ├── models.py
│   ├── templates
│   │   ├── add_package.html
│   │   ├── base_generic.html
│   │   ├── index.html
│   │   ├── new_developer.html
│   │   ├── packages
│   │   │   ├── contact.html
│   │   │   ├── developer_detail.html
│   │   │   ├── developer_list.html
│   │   │   ├── new_developer.html
│   │   │   ├── publication_detail.html
│   │   │   ├── publication_list.html
│   │   │   ├── tool_detail.html
│   │   │   └── tool_list.html
│   │   ├── thanks.html
│   ├── urls.py
│   └── views.py

Any assistance is greatly appreciated.

Upvotes: 0

Views: 634

Answers (1)

Aayush Agrawal
Aayush Agrawal

Reputation: 1394

Have you tried this:

def new_developer(request):
   if request.method == 'POST':
      form = NewDeveloper(request.POST)

      if form.is_valid():
         query = Developer.objects.filter(first_name=form.cleaned_data['first_name'], last_name=form.cleaned_data['last_name']).count()

         if query == 0:
            developer = Developer()
            developer.first_name = form.cleaned_data['first_name']
            developer.last_name = form.cleaned_data['last_name']

            developer.email = form.cleaned_data['email']
            developer.department = form.cleaned_data['department']
            developer.institution = form.cleaned_data['institution']
            developer.city = form.cleaned_data['city']
            developer.state = form.cleaned_data['state']

            developer.comments = form.cleaned_data['comments']

            developer.save()

      return HttpResponseRedirect('/packages/add_package/')

   else:
      form = NewDeveloper()

   return render(request, 'new_developer.html', {'form':form})

Replacing HttpResponseRedirect('/add_package/') with HttpResponseRedirect('/packages/add_package/')

If you want them to go to /packages/add_package you'll have to specify it. /add_package won't automatically add the /package in front just because the current URL has it

UPDATE:

Turns out the issue is caused because add_package is the name of the HTML file, NOT the definition that the router needs. From Django's point of view the name of the template is irrelevant, only thing that matters is where to route it, and for that it needs a function definition.

Following line change fixes it:

return HttpResponseRedirect('/packages/new_tool/')

Upvotes: 1

Related Questions