I am new to Django and I've been trying to develop a simple site that asks the user for their email address and height. It then saves it in the database and sends an email to the user and redirects them to a page saying that it was successful.
Now the problem is whenever I press 'Submit', I get a HTTP 405 method not allowed error.
# urls.py
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
#url(r'^success/$', views.SuccessView.as_view(), name='success'),
]
# forms.py
class HeightForm(forms.ModelForm):
class Meta:
model = Height
fields = ['email', 'height']
# views.py
class IndexView(generic.ListView):
form_class = HeightForm
template_name = 'heights/index.html'
def get_queryset(self):
return Height.objects.all()
class HeightFormView(View):
form_class = HeightForm
template_name = 'heights/success.html'
def get(self, request):
form = form_class(None)
def post(self, request):
print('a' * 1000)
form = form_class(request.POST)
if form.is_valid:
email = form.cleaned_data['email']
height = form.cleaned_data['height']
form.save()
return HttpResponseRedirect(template_name)
#render(request, template_name, {'form': form})
# index.html
{% extends 'heights/base.html' %}
{% block body %}
<h1>Collecting Heights</h1>
<h3>Please fill the entries to get population statistics on height</h3>
<form action="" method="post">
{% csrf_token %}
<input type="email" name="email" placeholder="Enter your email address" required="true"/><br />
<input type="number" min="50" max="300" name="height" placeholder="Enter your height in cm" required="true" /><br /><br />
<input type="submit" name="submit" />
</form>
Click to view all heights in database
{% endblock body %}
The code doesn't even get to the print('a' * 1000) line without generating an error. Chrome just goes to a This page isn't working page and displays HTTP ERROR 405.
I have Googled this error, but haven't found anthing helpful. Any help is appreciated
Thanks
You don't seem to have any URL defined for the HeightFormView. The form is rendered by the IndexView and posts back to itself; that view does not allow a POST method.
You would need to define a URL for HeightFormView and refer to it in the action via the {% url %} tag.
Add a route for your form to get submitted in urls.py and use the same in action. should work fine.
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^saveForm/$', views.HeightFormView.as_view(), name='form'),
]
And in your html form,
<form action="/saveForm" method="post">
Related
I'm new to Django, and I'm trying to submit a form to process the data in a view function, but I can't find why when I press the Send button it doesn't do anything. i read many other questions but were syntax related problems, which I believe is not my case.
Here's my form. It is in the new.html template:
<from action="{% url 'notes:create' %}" method="post">
{% csrf_token %}
<input type='text' name='note_name' id='note_name' placeholder='Title...'>
<input type='date' name='note_date' id='note_date'>
<input type="submit" value="Send">
</form>
Here it is urls.py:
app_name = 'notes'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('new/', views.new_note, name='new'),
path('output/', views.create_note, name='create')
]
And here the views.py file. Currently the create_note view only redirects to the index. I'm going to process the entered data once the form works correctly.
class IndexView(generic.ListView):
template_name = 'notes/index.html'
context_object_name = 'all_notes'
def get_queryset(self):
return Note.objects.all()
def new_note(request):
return render(request, 'notes/new.html')
def create_note(request):
return HttpResponseRedirect(reverse('notes:index'))
I have to create a site with auctions and I have an homepage which shows all the auctions active...
I want to redirect users to auctions details clicking on relative button but I have some problems with the hidden input request because it doesn't report the hidden value to my function ( def bid (request, auction) ) but I see it on the url bar after the csrfmiddlewaretoken (id=1), can you help me? (I have tried also with POST request...)
These are my codes:
views.py
def home(request):
auctions = Auction.objects.filter(status=True)
form = detailForm(request.GET or None)
if request.method == "GET":
id = request.GET.get("id")
if form.is_valid():
[bid(request,auction) for auction in auctions if auction.id==id]
else:
form = detailForm()
return render(request, "index.html", {"auctions":auctions, "form":form})
def bid(request, auction):
user = request.user
form = bidForm(request.POST)
if request.method == "POST":
bid = request.POST.get("endPrice")
if form.is_valid():
if bid > auction.startPrice:
auctionUpdate=form.save(commit=False)
auctionUpdate.endPrice=bid
auctionUpdate.winner=user
auctionUpdate.save()
else:
messages.warning(request, "Devi puntare una cifra superiore a quella vincente!")
else:
form = bidForm()
return render(request, "bid.html", {"form":form})
forms.py
class detailForm(forms.ModelForm):
class Meta:
model = Auction
fields = ("id",)
index.html
{% for auction in auctions %}
<--! I put all the informations about auctions -->
<form method="GET">
{% csrf_token %}
<input type="hidden" name="id" value={{auction.id}}>
<input type="submit">
{% endfor %}
</form>
Thanks to everyone!
Not sure if I understand your question correctly, so basically we have a list of auctions, and when a user clicks on a related button of an auction, the user will be redirected to another page.
In this model, you need to think about 2 views and 2 templates to handle them.
A ListView to list all your actions and a DetailView to handle the detail page of each auction. So you will have a home.html for your ListView and a bid.html for your auction detail.
I think the form submission should be implemented in your detail view (in your code the bid function), and the detail view should render a page with the bid.html template.
In your home.html you may want to just leave a link of each auction like:
{% for auction in auctions %}
<a type='button' href="{{ auction.get_absolute_url }}">{{ auction.name }}</a>
{% endfor %}
You need to add this get_absolute_url method in your Auction model, for example:
# models.py
def get_absolute_url(self):
return reverse("auction-detail", kwargs={"pk": self.pk})
Also in your routing:
# urls.py
urlpatterns = [
path('/', home, name='home'),
path('/auctions/<int:pk>/', bid, name='auction-detail'),
]
You need to pass auction to your context variable in your bid function as well, in order to refer to it in your template.
def bid (request, auction_id):
auction = Auction.objects.get_object_or_404(id=auction_id)
# ...
context = {'form': form, 'auction': auction}
return render(request, "bid.html", context)
And finally in your detail view template (bid.html), use the form to submit:
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="hidden" name="id" value={{auction.id}}>
<input type="submit">
</form>
Another suggestion is that try to use Class Based View such as ListView and DetailView in this case, which will handler your problem much easier. Check this article for more detail.
I am new to Django. i am unable to store the user input values into the postgres DB. I have created a tables using Models.py file and create a user interface using template file .How can i pass the vaues to the database using view.py file . someone help me plsz
For simple log-in
in users/views.py
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, logout,login
from django.http import HttpResponse, HttpResponseRedirect
def user_login(request):
if request.method == "POST":
phone = request.POST.get('phone')
password = request.POST.get('password')
user = authenticate(username=phone, password=password)
if user:
login(request,user)
return HttpResponseRedirect('/users/home')
else:
error = " Sorry! Phone Number and Password didn't match, Please try again ! "
return render(request, 'login/index.html',{'error':error})
else:
return render(request, 'login/index.html')
and in template login/index.html
<html>
<body>
{% if error %}
{{ error }}
{% endif %}
<form method="post" action="/users/login/">{% csrf_token %}
<input type=text placeholder="PhoneNo" name="phone">
<input type=password placeholder="Password" name="password">
<input type="submit" value="login">
</body>
</html>
for registration
login/signup.html
<html>
<body>
<form method=post action="users/signup/">{% csrf_token %}
<input type="text" name="phone" placeholde="Phone No">
<input type="text" name="email" placeholde="Email">
<input type="text" name="password1" placeholde="Password">
<input type="text" name="password2" placeholde="Password Again">
<input type="submit" value="signup">
</form>
</body>
</html>
in users/views.py
def users_signup(request):
if request.method == 'POST':
email = request.POST.get('email')
phone = request.POST.get('phone')
pass_1 = request.POST.get('password1')
pass_2 = request.POST.get('password2')
if pass_1 == pass_2:
user = User.objects.create_user(
username=phone,
email=email,
password=pass_1,
)
return HttpResponseRedirect("/")
else:
error = " Password Mismatch "
return render(request, 'login/signup.html',{"error":error})
else:
return render(request, 'login/signup.html')
main urls.py in main project folder where there is settings.py file would be
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^users/', include('users.urls')),
]
also url.py of app say "users"
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^login/', "users.views.user_login", name='login_url'),
url(r'^signup/', "users.views.user_signup", name='signup_url'),
)
Assuming your UI is based on a form, all you need to do in view.py is to handle a POST request which is sent from client when this form is submitted. So you define a method (say signup) which would get passed a request and possibly other parameters if needed. In it you do necessary validation (i.e. check if this user already exists) and return either new page with error messages via render() or a redirect to the next page if all is good.
More details in official tutorial which is quite good as correctly pointed out by #anuragal
I'm working on a little app that allows you to save specific location information about places you've been. The issue I'm having is that clicking the submit button on the 'save new location' page doesn't seem to be doing much of anything. It redirects to .../locationlib/savenew/, which is supposed to be the url that saves the form input as a new model object, but both according to debugging print statements and what actually happens, that function is just never called. I've had success with other forms using django but this one seems to be tripping me up. Can someone give me an idea of what's going on here?
views.py
def new(request):
return render(request, 'locationlib/new.html')
def savenew(request):
print 'savenew called'
name = request.POST['name']
latitude = float(request.POST['latitude'])
longitude = float(request.POST['longitude'])
desc = request.POST['description']
user = User.objects.get(username=str(request.POST['user']))
print 'all variables set'
l = Location(
name=name,
longitude=longitude,
latitude=latitude,
custDescription=desc,
user=user,
)
print 'l defined'
l.save()
print 'l saved'
return HttpResponseRedirect(reverse('locationlib:detail', args=[l.id]))
new.html
<div id='new-location-form'>
<form action="{% url 'locationlib:savenew' %}" method="post">
{% csrf_token %}
Name: <input type='text' name='name' value='Place Name' required><br>
User: <input type='text' name='user' value='User' required><br>
Longitude: <input type='text' name='longitude' value="Longitude Coordinate" required><br>
Latitude: <input type='text' name='latitude' value='Latitude Coordinate' required><br>
Description: <textarea name='description'>Description of Place</textarea><br>
<input type="submit" value="Save">
</form>
</div>
urls.py
urlpatterns = patterns( '',
...
url(r'new/', views.new, name='new'),
url(r'^savenew/', views.savenew, name='savenew'),
)
Your first URL pattern, new, is not anchored to the start of the string. That means that it matches anything that ends with "new" - and that includes "savenew". So your request for "savenew" is being caught by that pattern, and being sent to the new view.
Just put a ^ character at the front, as you have done with the other pattern.
try to use Modelforms
forms.py:
from django.forms import ModelForm
from myapp.models import Location
# Create the form class.
class LocationForm(ModelForm):
class Meta:
model = Location
view.py
def savenew(request):
if request.method == 'POST':
form = LocationForm(request.POST)
if form.is_valid():
new=form.save()
return HttpResponseRedirect(reverse(reverse('locationlib:detail', args=[new.id])))
return render(request,'reservetion/sign.html',{'form': form})
else:
form = SignForm()
return render(request, 'reservetion/sign.html',{'form': form})
new.html
<form action="{% url 'locationlib:savenew' %}" method="post">
{% csrf_token %}
{{ form}}
</form>
I want the user to be redirected to the last page after successful login whenever the user is prompted to login. Currently, it just redirects to the index page. I know this question has been asked several times and have also tried multiple ways of doing it but it doesnt work. I've also tried following this Django: Redirect to previous page after login
and it doesn't work because most of the stuff is already deprecated in 1.6. So I've the following code now and it gives me this 'url' requires a non-empty first argument. The syntax changed in Django 1.5, see the docs.
on line
129 : <h4><a class="writebtn"href=" {% url django.contrib.auth.views.login %} ?next={{request.path}}">Write Review</a></h4>
This is what i've so far
urls.py
url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'meddy1/login.html'}, name="login")
login.html
<form method="post" action="{% url 'django.contrib.auth.views.login' %}"> {% csrf_token %}
<input type="text" class="form-control" id="username" placeholder="Username" name="username">
<input type="password" class="form-control" id="inputPassword" placeholder="Password" name="password">
<button class="btn btn-primary" type="submit" name="submit" id="ss-submit">LOG IN</button>
<input type="hidden" name="next" value="{{ next }}" />
</form>
I've this in my template to see if the user is authenticated to write a review - if not logged in it renders the login page but then it redirects to the index page
{% if user.is_authenticated and reviewed == False %}
<h4><a class="writebtn"href="/usercontent/{{doctor.id}}/">Write Review</a></h4>
{% elif user.is_authenticated and reviewed == True %}
<h4><a class="writebtn"href="">Already Reviewed!</a></h4>
{% else %}
<h4><a class="writebtn"href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Write Review</a></h4>
{% endif %}
views.py
#login_required
def addContent(request, id):
d = getVariables(request)
doctor = Doctor.objects.get(id=id)
params = {}
params.update(csrf(request))
if request.user.is_authenticated():
user = request.user
ds = DoctorSeeker.objects.get(user=user)
d['doctorseeker'] = ds
if request.method == "POST":
form = UserContentForm(request.POST)
if form.is_valid():
time = form.cleaned_data['time']
comment = form.cleaned_data['comment']
if request.POST.get('Like') == 'Like':
con = UserContent(time=time, comment = comment, liked = True, disliked = False, doctor_id = doctor.id, user_id = request.user.id)
doctor.likes += 1
doctor.netlikes = doctor.likes - doctor.dislikes
doctor.save()
con.save()
elif request.POST.get('Like') == 'Dislike':
con = UserContent(time=time, comment = comment, liked = False, disliked = True, doctor_id = doctor.id, user_id = request.user.id)
doctor.dislikes +=1
doctor.netlikes = doctor.likes - doctor.dislikes
doctor.save()
con.save()
url = '/docprofile/%s' % str(doctor.id)
return HttpResponseRedirect(url)
else:
form = UserContentForm()
d.update({'doctor': doctor, 'UGC': UserContent.objects.all(),
'form': form })
return render(request, 'meddy1/usercontent.html',d)
For the following template code to work:
Link
The following must be in place:
You must have a reference to django.contrib.auth.views.login in your `urls.py:
url(r'^login/$', 'django.contrib.auth.views.login')
You must have a template that resolves to registration/login.html or you can specify a specific template path (which must exist) in the your url conf:
url(r'^login/$',
'django.contrib.auth.views.login',
{'template_name': '<your template>'}
)
In your settings.py, you must have:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
...
)
This automatically adds the request variable gets to your template context.
You must render your template with a RequestContext. There are many ways to do that, but the most simple is:
from django.shortcuts import render
def view(request):
...
return render(request, '<template>', {<other context variables>})
Using a RequestContext causes the django.core.context_processors.request context processor to run.