Django Page not found with post request - python

So I am new to Django and I'm trying to create a HTML form (just following the tutorial for the name input) and I can input the name but can't direct to the /thanks.html page.
$ views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
print(form)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/polls/thanks.html')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
$ name.html
<html>
<form action="/polls/thanks.html" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
<html>
$ /mysite/urls
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
$ mysite/polls/urls.py
from django.urls import path
from polls import views
urlpatterns = [
path('', views.get_name, name='index'),
]
When I go to to the page, I can enter my name fine but then when I submit i get
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
polls/ [name='index']
admin/
The current path, polls/thanks.html, didn't match any of these.
Even though thanks.html is inside /polls
Sorry if the fix is super easy I just haven't used Django before.
Thanks :)

Create a view called thanks in views.py
def thanks(request):
return render(request, 'thanks.html')
Now, Link the /poll/thanks/ url to the thanks template by adding path('thanks/', views.thanks, name='thanks') to your urls.py of the polls app.
$ mysite/polls/urls.py
from django.urls import path
from polls import views
urlpatterns = [
path('thanks/', views.thanks, name='thanks'),
]
Finally change the following line in your get_name view
return HttpResponseRedirect('/polls/thanks/')

Change your main urls.py:
url(r'^polls/', include('polls.urls')),
And in your app's urls.py:
url(r'^$', views.get_name, name='index'),
And in your views.py change to:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return render(request, 'thanks.html')

Related

Django HTMLForms AttributeError AttributeError: module 'polls.views' has no attribute 'index'

I'm using Django to create a simple HTML input page, right now I am just using the tutorial for Django Forms but I get the error AttributeError: module 'polls.views' has no attribute 'index'
Here are all the relevant files:
This is where the Error is happening:
$ mysite/polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
This is views.py:
$ polls/views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
and this is forms.py
$ /polls/forms.py
from Django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
Here is name.html:
$ /polls/name.html
<html>
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
<html>
I am so confused as to why this is happening because when I used it with the Writing your first Django app tutorial it worked but when I use a form it doesn't
Thanks in advance
Your view name is not index but get_name
urlpatterns = [
path('', views.get_name, name='index'),
]
Your polls/urls.py:
from django.urls import path
from . import views
app_name = 'polls' # add this line
urlpatterns = [
path('', views.index, name='index'),
]

Django - Urls are appending to one another

I'm making a web app in django and currently I'm facing this problem. I have a dashboard page and an upload page. There's a button in dashboard page which links to the upload page. but whenever I click the button then the upload page url appends the dashboard page.
below is the code:
views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from .models import Registration
from .forms import UploadForm
from django.urls import reverse
# Create your views here.
def homepage(request):
return render(request, 'index.html', {})
def dashboard(request):
posts = Registration.objects.all()
return render(request, "dashboard.html", {'posts': posts})
def upload(request):
form = UploadForm()
return render(request, "upload.html", {'form': form})
def uploadimage(request):
if request.method == 'POST':
form=UploadForm(request.FILES['image'], request.POST)
if form.is_valid():
pic = request.FILES['image']
desc = request.POST
post = Registration(pic='pic', desc='desc')
post.save()
urls.py
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns = [
path('', views.homepage, name='homepage'),
path('dashboard/', views.dashboard, name='dashboard'),
path('upload/', views.upload, name='upload'),
path('create/', views.uploadimage, name='uploadimage'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
dashboard.html
<div class="profile">
<div class="left-s col s12 m3 l3">
<div class="profile-overview">
<img src="{%static 'images/group.jpg' %}" alt="profile-pic" class="circle responsive-img">
<p>Daljit Singh</p>
<p>Lorem ipsum dolor sit amet.</p>
</div>
<hr>
<div class="container">
<ul>
<li>About</li>
<li>Friends</li>
<li>Photos</li>
<li>Likes</li>
</ul>
</div>
<hr>
<button>Upload post</button>
</div>
error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/dashboard/upload/
Using the URLconf defined in main.urls, Django tried these URL patterns, in this order:
[name='homepage']
dashboard/ [name='dashboard']
upload/ [name='upload']
create/ [name='uploadimage']
^media\/(?P<path>.*)$
The current path, dashboard/upload/, 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.
Help would be appreciated.
It should be - Upload post
If you enter '/' (/upload/) before the path it will append to the base URL and if '/' (upload/) doesn't exist then it will append to the existing path.
Or the Different way suggested in the comment -
Upload post

Django - delete button is not redirecting to the correct path

I am following a tutorial to make a to-do list website. Upon trying to implement a delete button, I am encountering this error.
Page not found (404) Request Method: GET Request
URL: http://localhost:8000/%7B%25%20url%20'delete'%20things.id%20%25
Using the URLconf defined in todo.urls, Django tried these URL
patterns, in this order:
admin/ [name='home'] delete/"" [name='delete'] The current
path, {% url 'delete' things.id %, didn't match any of these.
Relevant code:
views.py
from django.shortcuts import render, redirect
from .models import List
from .forms import ListForm
from django.contrib import messages
# Create your views here.
def home(request):
if request.method == 'POST':
form = ListForm(request.POST or None)
if form.is_valid():
form.save()
all_items = List.objects.all
messages.success(request, ('Item Has Been Added To List!'))
return render(request, 'home.html', {'all_items': all_items})
else:
all_items = List.objects.all
return render(request, 'home.html', {'all_items': all_items})
def delete(request, list_id):
item = List.objects.get(pk=list_id)
item.delete()
messages.success(request, ('Item Has Been Deleted!'))
return redirect('home')
home.html
<tr>
<td>{{ things.item }}</td>
<td><center>{{ things.completed }}</center></td>
<td><center> Delete</center></td>
</tr>
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name="home"),
path('delete/<list_id>', views.delete, name="delete"),
]
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name="home"),
path('delete/<int:list_id>/', views.delete, name="delete"),
]
You need to specify the int type in the url.
And also the trailing /
You need a regular expression to say a number is coming
path('delete/(?P<list_id>)[\d]+)/$', views.delete, name="delete"),

What does 'Reverse' means in errors when running Django?

I'm trying to run a blog build with django on the browser. And I got this error:
NoReverseMatch at /
Reverse for 'blog.views.post_detail' not found.
'blog.views.post_detail' is not a valid view function or pattern name.
My url.py of my app looks like:
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^$', views.post_list),
url(r'^post/(?P<pk>[0-9]+)/$', views.post_detail),
]
It seems that when I type 127.0.0.1:8000/.
The url will direct to views.post_list.
And my views.py looks like:
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__isnull=False)
return render(request, 'blog/post_list.html', {'posts': posts}
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
post_list() will render the request with post_list.html.
Inside post_list.html, the error comes from the line:
<h1>{{ post.title }}</h1>
I don't really understand what 'Reverse' means in the error message. 'blog.views.post_detail' does exist in views.py. I think I got everything needed for the code and can't figure out what went wrong.
I'm new to django, sorry if the question is basic and thanks for answering!
Django 1.10 removed the ability to reverse urls by the view's dotted import path. Instead, you need to name your url pattern and use that name to reverse the url:
urlpatterns = [
url(r'^$', views.post_list, name='post-list'),
url(r'^(?P<pk>\d+)/$', views.post_detail, name='post-detail'),
]
And in your template:
<h1>{{ post.title }}</h1>
It seems that your urls.py should be as follows:
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^$', views.post_list),
url(r'^(?P<pk>\d+)/$', views.post_detail),
]
You should define a name for your url:
urlpatterns [
url(r'^$', views.post_list,name=post_list),
]
then use url tag like this:
AppName is you django application name.

How to make a simple contact form using Django?

I am new to Django 1.9 and I am currently coding a website. I am trying to make a contact form to go on the contact page. I have used the following code - which is in the a file called email.html:
{% extends 'blog/base.html' %}
<form method="post">
{% csrf_token %}
{{ form }}
<div class="form-actions">
<button type="submit">Send</button>
</div>
</form>
I've defined it in the view.py file:
from .forms import PostForm, ContactForm
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
def email(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(subject, message, from_email, ['nmam.ltd#gmail.com'])
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('thanks')
return render(request, "blog/email.html", {'form': form})
def thanks(request):
return HttpResponse('Thank you for your message.')
.....
As well as in the forms.py file:
from django import forms
class ContactForm(forms.Form):
from_email = forms.EmailField(required=True)
subject = forms.CharField(required=True)
message = forms.CharField(widget=forms.Textarea)
Also, in the urls.py file:
from django.conf.urls import patterns, url
from . import views
urlpatterns = [
url(r'^general.html/$', views.general, name='general'),
url(r'^dcmain.html/$', views.dcmain, name='dcmain'),
url(r'^dcmain.html/big_data.html/$', views.big_data, name='big_data'),
url(r'^dcmain.html/Data_Architecture.html/$', views.Data_Architecture, name='Data_Architecture'),
url(r'^dcmain.html/BI_MI.html/$', views.BI_MI, name='BI_MI'),
url(r'^dcmain.html/Master_Data.html/$', views.Master_Data, name='Master_Data'),
url(r'^dcmain.html/Data_Q.html/$', views.Data_Q, name='Data_Q'),
url(r'^dcmain.html/Project_M.html/$', views.Project_M, name='Project_M'),
url(r'^email.html/$', views.email, name='email'),
url(r'^thanks/$', views.thanks, name='thanks'),
]
When I link the email.html file to the main page and click on the link and it just shows the home page even though the url says I am on the email.html page (shown below):
I am totally new to programming in Django. I have tried researching it however, I can't find a solution. Please can someone help me.
Your URLs are most likely the problem. You can read more on Django URLs here.
Note, as the Django docs mention, the first URL pattern which matches the requested URL will be used. As a basic rule of thumb, I recommend putting your more specific URL patterns before your blank url patterns. For instance:
urlpatterns = [
url(r'^email.html/$', views.email, name='email'),
url(r'^thanks/$', views.thanks, name='thanks'),
url(r'^$', views.index, name='some_name'),
]
If this urls.py file is being included from a project urls.py file, you'll want these urls to be included before your root url pattern.
urlpatterns = [
url(r'^blog/', include('blog.urls', namespace='blog'),
url(r'', views.site_home, name='site_home'),
]
Which would then make your url to this page
Email
Which would render as
Email

Categories

Resources