I'm creating a Contact page on my portfolio site which when the user fills out and submits will automatically send it as an email to my personal email account. But when I hit Submit I get "Method Not Allowed (POST):/contact/" in my terminal, "HTTP ERROR 405" in my browser and no email in my account.
My HTML:
<form action="" method="POST">
{% csrf_token %}
<div class="row form-group">
<div class="col">
<input name="f-name" type="text" class="form-control" placeholder="First name" required>
</div>
<div class="col">
<input name="s-name" type="text" class="form-control" placeholder="Last name" required>
</div>
</div>
<div class="form-group">
<input name="email" type="email" class="form-control" id="email-input" aria-describedby="emailHelp" placeholder="name#mail.com" required>
<small id="emailHelp" class="form-text text-muted">I Wont Share Your Email!</small>
</div>
<div class="form-group text-center">
<textarea name="e-message" class="form-control" id="exampleFormControlTextarea1" rows="3" placeholder="your message..." required></textarea>
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
My views.py:
class ContactView(TemplateView):
template_name = 'contact.html'
def send_message(self, request):
if request.method == 'POST':
message = request.POST['f-name', 's-name', 'email', 'e-message']
send_mail('Contact Form', message,['email#gmail.com'],
fail_silently=False)
return render(request, 'thanks.html')
My project urls.py
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views
from blog import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
path('projects/', views.ProjectView.as_view(), name='projects'),
path('blog/', views.BlogView.as_view(), name='blog'),
path('contact/', views.ContactView.as_view(), name='contact'),
path('thanks/', views.ThanksView.as_view(), name='thanks'),
My application urls.py
from django.conf.urls import url
from blog import views
app_name = 'blog'
urlpatterns = [
url(r'^$', views.AboutView.as_view(), name='about'),
url(r'^projects/$', views.ProjectView.as_view(), name='projects'),
url(r'^blog/$', views.BlogView.as_view(), name='blog'),
url(r'^contact/$', views.ContactView.as_view(), name='contact'),
url(r'^thanks/$', views.ThanksView.as_view(), name='thanks'),
Iv been searching for similar answers for a few hours and anything similar hasnt helped so far Maybe I should re build my form in Django forms? I dont want to risk going too far changing too much and breaking my site!
Django does not support post method on template view implicitly. You have to define post method yourself in template view like this
class ContactView(TemplateView):
template_name = 'contact.html'
def post(self, request, *args, **kwargs):
message = request.POST['e-message']
send_mail('Contact Form', message,['email#gmail.com'], fail_silently=False)
return render(request, 'thanks.html')
The rest will be handled automatically
Related
The project I am working on is the blogging website and I am stuck at this signup process, I want it to function like after signup, the user lands on the home page, but instead this is showing me the above error
views.py:
def handleSignup(request):
if request.method == 'POST':
username = request.POST['username']
fname = request.POST['fname']
lname = request.POST['lname']
email = request.POST['email']
pass1 = request.POST['pass1']
pass2 = request.POST['pass2']
# creating users
myuser = User.objects.create_user(username, email, pass1)
myuser.first_name = fname
myuser.last_name = lname
myuser.save()
messages.success(request, 'your account have been successfully created!')
return redirect(request, "/home.html")
else:
return HttpResponse("error 404 not found")
urls.py:
urlpatterns = [
path("", views.home, name="home"),
path("contact/", views.contact, name="contact"),
path("about", views.about, name="about"),
path("signup/", views.handleSignup, name="handleSignup"),
]
forms in base.html:
<form action="/signup/" method="post">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" name = 'username' placeholder="choose a unique username">
</div>
<div class="form-group">
<label for="fname">Firstname</label>
<input type="text" class="form-control" id="fname" name = 'fname' placeholder="First Name">
</div>
<div class="form-group">
<label for="lname">Lastname</label>
<input type="text" class="form-control" id="lname" name= 'lname' placeholder="Last Name">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" id="email" name = 'email' placeholder="email#example.com">
</div>
<div class="form-group">
<label for="pass1">Choose Password</label>
<input type="password" class="form-control" name = 'pass1' id="pass1">
</div>
<div class="form-group">
<label for="pass2">Confirm password</label>
<input type="password" class="form-control" name = 'pass2' id="pass2">
</div>
{% csrf_token %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
the error log:
NoReverseMatch at /signup/
Reverse for '<WSGIRequest: POST '/signup/'>' not found. '<WSGIRequest: POST '/signup/'>' is not a valid view function or pattern name.
Request Method: POST
Request URL: http://127.0.0.1:8000/signup/
Django Version: 3.1
Exception Type: NoReverseMatch
Exception Value:
Reverse for '<WSGIRequest: POST '/signup/'>' not found. '<WSGIRequest: POST '/signup/'>' is not a valid view function or pattern name.
Exception Location: C:\Users\jayant nigam\projects\practise\lib\site-packages\django\urls\resolvers.py, line 685, in _reverse_with_prefix
Python Executable: C:\Users\jayant nigam\projects\practise\Scripts\python.exe
Python Version: 3.8.5
Python Path:
['C:\\Users\\jayant nigam\\projects\\everythingcs',
'C:\\Python38\\python38.zip',
'C:\\Python38\\DLLs',
'C:\\Python38\\lib',
'C:\\Python38',
'C:\\Users\\jayant nigam\\projects\\practise',
'C:\\Users\\jayant nigam\\projects\\practise\\lib\\site-packages']
Server time: Mon, 28 Sep 2020 17:39:46 +0000
the error line which it is highlighting:
return redirect(request, "/home.html")
You specified path("", views.home, name="home") in your urls.py, therefore you can just do:
return redirect("/")
You shouldn't be passing request as a first argument to redirect(), you only need to provide a URL (relative or absolute) most of the time.
Actually, as a best practice, that URL should be provided using reverse, e.g.:
from django.urls import reverse
...
return redirect(reverse('home'))
See the doc for redirect().
So I have probably the simplest task you could ever wish for with an html form that I cannot solve.
I want to input a brand name into a search bar, click submit and it redirect to the url/brand/[input]
I already have a working view for the urls setup in django. How would I structure the form to actually create my desired url?
<form method="GET" action="">
<input type="text" name="brand" id="brand" placeholder="Search..." aria-label="Search">
<button type="submit">Search</button>
</form>
views.py
class GetByBrand(ListView):
def get(self, request, brand):
urls.py
urlpatterns = [
path('', GetListView.as_view(), name='home'),
path('brands/<str:brand>/', GetByBrand.as_view())
]
<form method="GET" action="brands/">
<input type="text" name="brand" id="brand" placeholder="Search..." aria-label="Search">
<button type="submit">Search</button>
in URLs(import views by from. import views)
urlpatterns = [
path('brands/', views.GetByBrand),
]
in Views
from django.http import HttpResponse
def GetByBrand(request):
s = request.GET['brand']
return HttpResponse(s)
OR use AJAX in Javascript in your HTML file
$('#brand').on('submit',function(e){
var brand = $('input[name=brands]')
$.get("brands/"+brand, function(data, status){
alert("Data: " + data + "\nStatus: " + status);
});
})
So I basically solved this by using the code I had previously tried which is identical to what Wagas Develper recommended. What I had not done though was add this last line to the urls.py in the main project folder. (and I'm still not sure why this solved it but found the solution from throwing crap at the wall)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('shoes.urls')),
path('brands/', include('shoes.urls'))
For anyone curious about how the class based view is structured now.
class GetByBrand(ListView):
def get(self, request, brand):
get_results = request.GET.get('q')
The urls.py in the same directory as views.py (within app dir not main project dir)
urlpatterns = [
path('', GetListView.as_view(), name='home'),
path('brands/<str:brand>/', GetByBrand.as_view()),
path('brand_results/', GetByBrand.as_view(), name='b')
]
HTML Form
<form method="GET" class="form-inline my-2 my-lg-0" action="{% url 'b' %}">
<input class="form-control mr-sm-2 search-btn" type="text" name="q" value="{{request.GET.q}}" placeholder="Search..." aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
I am using this code for a register form. But the post request doesn't work and give me an error :
ValueError at /register/
The view users.views.RegisterView didn't return an HttpResponse object. It returned None instead.
views.py
class RegisterView(View):
def get(self,request):
register_form = RegisterForm()
return render(request, 'register.html',{'register_form':register_form})
def post(self,request):
register_form = RegisterForm(request.POST)
if register_form.is_valid():
user_name = request.POST.get("email", "") user_psw = request.POST.get("password", "")
user_profile=UserProfile()
user_profile.username = user_name
user_profile.email = user_name
user_profile.password=make_password(user_psw)
user_profile.save()
send_register_email(user_name,"register")
pass
urls.py
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
import xadmin
from users.views import LoginView , RegisterView
import xadmin
urlpatterns = [
path('xadmin/', xadmin.site.urls),
path('',TemplateView.as_view(template_name="index.html"),name="index"),
path('login/',LoginView.as_view(),name="login"),
path('register/',RegisterView.as_view(),name="register"),
path("captcha/", include('captcha.urls'))
]
forms.py
class RegisterForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
captcha = CaptchaField(error_messages={"invalid":"please input correctly"})
register.html
<div class="tab-form">
<form id="email_register_form" method="post" action="{% url 'register' %}" autocomplete="off">
<input type='hidden' name='csrfmiddlewaretoken' value='gTZljXgnpvxn0fKZ1XkWrM1PrCGSjiCZ' />
<div class="form-group marb20 ">
<label>邮 箱</label>
<input type="text" id="id_email" name="email" value="None" placeholder="请输入您的邮箱地址" />
</div>
<div class="form-group marb8 ">
<label>密 码</label>
<input type="password" id="id_password" name="password" value="None" placeholder="请输入6-20位非中文字符密码" />
</div>
<div class="form-group marb8 captcha1 ">
<label>验 证 码</label>
{{ register_form.captcha }}
<img src="/captcha/image/2f3f82e5f7a054bf5caa93b9b0bb6cc308fb7011/" alt="captcha" class="captcha" /> <input id="id_captcha_0" name="captcha_0" type="hidden" value="2f3f82e5f7a054bf5caa93b9b0bb6cc308fb7011" /> <input autocomplete="off" id="id_captcha_1" name="captcha_1" type="text" />
</div>
<div class="error btns" id="jsEmailTips"></div>
<div class="auto-box marb8">
</div>
<input class="btn btn-green" id="jsEmailRegBtn" type="submit" value="注册并登录" />
<input type='hidden' name='csrfmiddlewaretoken' value='5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy' />
{% csrf_token %}
</form>
</div>
request information
Request information
USER
AnonymousUser
GET
No GET data
POST
Variable Value
csrfmiddlewaretoken
'9dQylxY3htVbBMNFunnYwgnarkfjSVioz5rhu0uADk0ShssTFGl9144OEwJoUlPX'
email
'1#1.com'
password
'123456'
captcha_0
'2f3f82e5f7a054bf5caa93b9b0bb6cc308fb7011'
captcha_1
''
FILES
No FILES data
no matter whether the verification code I input is wrong or right, the error is always The view users.views.RegisterView didn't return an HttpResponse object. It returned None instead.
Django's view should return some response.
From doc:
A view function, or view for short, is simply a Python function that takes a Web request and returns a Web response. This response can be the HTML contents of a Web page, or a redirect, or a 404 error, or an XML document, or an image . . . or anything, really.
So you need to add return statement to post() method, e.g. like this:
def post(self,request):
...
return render(request, 'register.html',{'register_form':register_form})
I am following the documentation of the Django Forms but I do not know why my form does not want to show up !
I am creating a form that will get an email en create invitation for user to sign in using this app :https://github.com/bee-keeper/django-invitations
My forms.py:
class InviteForm(forms.Form):
email1 = forms.EmailField(label='Email 1')
My Views.py:
from django.shortcuts import render
from django.views.generic import TemplateView
from .forms import InviteForm
class candidateIndex(TemplateView):
template_name= 'candidateIndex.html'
class HRIndex(TemplateView):
template_name= 'HRindex.html'
def create_invite(request):
if request.method == 'POST':
form = InviteForm(request.POST)
if form.is_valid:
email = form.cleaned_data['email1']
invite = Invitation.create('form.email1')
invite.send_invitation(request)
print("The mail was went")
else:
print("Your form is not valid")
else:
form = InviteForm()
return render(request, 'HRindex.html', {'form': form})
My HTML:
{% extends 'base.html' %}
{% block body %}
<div class="jumbotron">
<h1>Welcome to SoftScores.com</h1>
<h2>Team analytics platfom</h2>
<h3>Welcome to {{user.username}}, it is your Page</h3>
</div>
<div class="container">
<p>
<a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample">
Create a new team
</a>
</p>
<div class="collapse" id="collapseExample">
<div class="card card-body">
In order to create a new team please invite new members. A link will be sent to them in order to give the access to the application
</div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
</div>
</div>
urls.py:
from django.conf.urls import url
from website import views
app_name = 'website'
urlpatterns = [
url(r'^candidateIndex/$', views.candidateIndex.as_view(), name='candidate_index'),
url(r'^HRIndex/$', views.HRIndex.as_view(), name='HR_index'),
]
When it render the page I get only the button but the form does not seems to work
Do you habe any idea ?
You HR_index url is being handled by the HRIndex view, but this does not have any code to handle the form.
url(r'^HRIndex/$', views.HRIndex.as_view(), name='HR_index'),
Since a TemplateView is not really suited to handling a form, it would be better to modify the URL pattern to use the create_invite view instead:
url(r'^HRIndex/$', views.create_invite, name='HR_index'),
I practice how to use django login , but it can't redirect to the page before login
Please teach me how to do it Thank you very much
My project name is :proj
And I have an app name: app1
when I go to http://127.0.0.1:8000/f/index/ it will redirect to http://127.0.0.1:8000/accounts/login/?next=/f/index/
and after I enter the username and password,
I want to redirect to http://127.0.0.1:8000/f/index/ ( by the parameter ?next=/f/index/) but don't know how to do .
app1/views.py :
from django.contrib.auth.decorators import login_required
#login_required
def index(request):
logger.info('test')
....
proj/urls.py:
urlpatterns = patterns('',
url(r'^accounts/login/$', 'proj.views.login'),
url(r'^accounts/logout/$', 'proj.views.logout'),
url(r'^accounts/auth/$', 'proj.views.auth_view'),
proj/views.py
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
def login(request):
c={}
c.update(csrf(request))
return render_to_response('proj/login.html',c)
def auth_view(request):
username = request.POST.get('username','')
password = request.POST.get('password','')
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
# return HttpResponseRedirect(request.POST.get('next')) #not work
else:
return HttpResponseRedirect('/accounts/invalid')
proj/login.html:
{% if form.errors %}
<p class="error">Sorry.that's not valid </p>
{% endif %}
<form action="/accounts/auth/?next={{ request.get_full_path|urlencode }}" method="post">{% csrf_token %}
<label for="username" >User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password" >Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
</form>
try this in views.py:
if user is not None:
auth.login(request,user)
return HttpResponseRedirect('/f/index/')
when you type url, and you are not login before, and django redirect to the url :http://127.0.0.1:8000/accounts/login/?next=/f/index/
after entering your username and password, and click submit button, django redirect you automatically to http://127.0.0.1:8000/f/index/
using URLresolver.