Method Not Allowed (POST) using DeleteView - python

I am new to Django and i using Class based views to add a delete option to my Restaurant List, However when i click the delete button i am getting a blank screen and getting the following error in the console
"Method Not Allowed (POST):"
Below is my code
views.py
from __future__ import unicode_literals
from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView, ListView, DetailView,
CreateView,DeleteView
from django.urls import reverse_lazy
class RestaurantDeleteView(DeleteView):
model = RestaurantLocation
success_url = reverse_lazy('restaurants:list')
urls.py
from django.conf.urls import url, include
from .views import (
RestaurantListView,
RestaurantDetailView,
RestaurantCreateView,
RestaurantDeleteView,
)
urlpatterns = [
url(r'^create/$', RestaurantCreateView.as_view(), name= 'create'),
url(r'^$',RestaurantListView.as_view(), name= 'list'),
url(r'^(?P<slug>[\w-]+)/$',RestaurantDetailView.as_view(),
name="detail"),
url(r'^(?P<slug>[\w-]+)/delete/$', RestaurantDeleteView.as_view(),
name="restaurant-delete"),
]
delete.html
<form method="post" action="" >{% csrf_token %}
<p>Are you sure you want to delete <strong> {{ obj }}</strong>?</p>
<input type="submit" value="DELETE" />
</form>

method in your delete.html is currently "t", change to "post" and see if that works.

Your form action is pointing to root url that is /.
This route is determined by the RestaurantListViews and it is accesed via GET method.
In your example, you are trying to access this using POST, thus you're getting the error.
To make use of your RestaurantDeleteView change the action property in your form to point to an existing restaurant, like:
<form method="post" action="{your_existing_restaurant_slug}/delete" >
{% csrf_token %}
...
...

Related

Why am I getting no reverse match error in django 3.2?

I am making a simple todo list application but while adding a delete button, I am receiving the error.
I tried many things searching on internet but couldn't solve the issue, probably because i am new to django.So, your help will be very important.
urls.py(of app):
from django.conf.urls import url
from django.urls import path
from . import views
urlpatterns=[
path('',views.home,name='home'),
url('delete/<str:id>', views.delete_data,name='deldata'),
]
views.py:
from django.shortcuts import get_object_or_404, render,redirect
from todo.models import value
from django.http import HttpResponseRedirect
# Create your views here.
from .forms import TitleForm
from django.urls import reverse
def home(request):
values=value.objects.all()
form=TitleForm
if request.method=='POST':
form=TitleForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
form=TitleForm()
return render(request,'home.html',{'values':values,'form':form})
#delete
def delete_data(request, id ):
ggwp=value.objects.get(id=id)
if request.method=="POST":
ggwp=value.objects.get(id=id)
ggwp.delete()
return HttpResponseRedirect(reverse('deldata', kwargs={'id':id}))
context={'ggwp':ggwp}
return render(request,'/',context)
models.py:
from django.db import models
# Create your models here.
class value(models.Model):
task=models.CharField(max_length=200)
complete=models.BooleanField(default=False)
created=models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.task
home.html(One and only html page):
<h3>TO DO LIST</h3>
<form method="POST" action="\">
{% csrf_token %}
{{form.task}} <input type='submit' name='add' value="add" >
</form>
{% for val in values %}
{{val}}
<form action="{% url 'deldata' val.id %}" method="POST" class="in-line">
{% csrf_token %}
<input type="submit" value="Delete" >
</form>
{% endfor %}
traceback:
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'deldata' with arguments '(15,)' not
found. 1 pattern(s) tried: ['delete/<str:id>']
[05/Oct/2021 22:37:17] "GET / HTTP/1.1" 500 127858
Its my first question, so sorry if I have made any mistakes while writing the question.
You are using path(…) [Django-doc] syntax with the url(…) function [Django-doc]. You should work with a path(…) here:
urlpatterns=[
path('',views.home,name='home'),
# &downarrow; path, not url
path('delete/<str:id>/', views.delete_data,name='deldata'),
]
Normally paths also end with a slash, altough that is not required, it is common.
Note: As of django-3.1, url(…) [Django-doc] is
deprecated in favor of re_path(…) [Django-doc].
Furthermore a new syntax for paths has been introduced with path converters: you
use path(…) [Django-doc] for that.

django : unable to call a python function by clicking submit button

Trying to call Installation function when we click a submit button on HTML Page and taking the data from HTML only,i am new to django.
Help me out..!
Views File:
from .forms import Details
from django import forms
from django.shortcuts import render
from django.http import HttpResponseRedirect
from . import installation
def output(request):
if request.method == 'POST':
details=Details(request.POST)
if details.is_valid():
Obj=details.cleaned_data
path=Obj['Path']
device_type=Obj['Device']
image_version=Obj['Version']
return installation()
else:
raise TypeError
App/urls.py File:
from django.conf.urls import url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'',views.output,{'template_name':'home_page.html'}),
]
Forms.py File :
from django import forms
class Details(forms.Form):
Device=forms.CharField(required=True, label='Device_Type', max_length=32)
Path=forms.FileField(required=True, label='Path_to_install_build')
Version=forms.CharField(required=True, label='Version_type',max_length=32)
Where is your HTML? if your frontend (HTML) is not reaching your backend at your views, probabily your action is not right, so check if your form have the right action
<form action="/" method="POST">
{% csrf_token %}
<!-- Rest of the HTML code to your form -->
<input type="submit">Submit</input>
</form>
Im setting you action to / because you using root path to your views, if you change it to like detail, the action should be /detail/
BTW you can use the built-in form from django
{% csrf_token %}
{{ form.as_p }}
<input type="submit">Submit</input>

NoReverseMatch at /index/

I have been through all of the similar issues and I have gotten nowhere and I have gone through the djangogirls and the officail Django tutorials and as far as I can tell it should be working.
In the polls/templates/index.html file I have this:
[...]
{% if forms %}
<ul>
{% for form in forms %}
<li>
<h1><a href="{% url 'form_detail' pk=form.pk %}">
{{ form.fname }}
</a></h1>
[...]
In my polls/urls.py file I have this:
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
[...]
url(r'^index/$', 'polls.views.site_index'),
[...]
url(r'^form/(?P<pk>\d+)/$', views.form_detail, name='form_detail'),
[...]
In my polls/views.py file I have this:
from django.shortcuts import render, render_to_response, redirect, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from .models import Nform, Choice, Question, Post
from django.template import loader
from django.utils import timezone
from django.views import generic
from django.contrib import auth
from django.db import models
from .form import PostForm
def site_index(request):
forms = Nform.objects.order_by('-published_date')
return render_to_response('polls/index.html', {'forms': forms})
def form_detail(request, pk):
current_form = get_object_or_404(Nform, pk=pk)
fame = current_form.fname
latest_question_list = Question.objects.filter(for_form=fame).order_by('-pub_date')
choice_quest_list = []
text_quest_list = []
form = PostForm()
for i in range(len(latest_question_list)):
if len(latest_question_list[i].choice_set.all()) == 0:
text_quest_list.append(latest_question_list[i])
else:
choice_quest_list.append(latest_question_list[i])
return render(request, 'polls/read_only.html', {'choice_quest_list': choice_quest_list, 'text_quest_list': text_quest_list, 'form_name': fame, 'form': form})
[...]
I am assume that I have made a very simple mistake somewhere and I would be very grateful to anyone who finds it.
See this issue for pics.
Here is a link to my code.
Thanks :)
This is happening because you have defined a variable named app_name in your application urls.py.
When you define that variable, it becomes your url namespace.
You either have to reverse your url like this:
<h1><a href="{% url 'polls:form_detail' pk=form.pk %}">
or remove the app_name variable to use the url name directly.
Read more about reversing url names # django-docs

"' object has no attribute 'get' Error

Have stuck here for 2 days. Hoping to get some enlightenment. The error code here is "'inputform' object has no attribute 'get'". I highly suspect the error is because of the forms.py. I want to make a dynammic choice field list there.
Model.py
from django import forms
from django.forms import ModelForm
from django.db import models
from dupont.models import dupont
class input(models.Model):
...
Region=models.CharField(max_length=100)
Forms.py
from django import forms
from django.forms import ModelForm
from .models import input
from anothermodel.models import A
from django.contrib.auth.models import User
import Queue
class inputform(forms.ModelForm):
regionlist = forms.ChoiceField(label=u'Region',choices=())
def __init__(self,*args,**kwargs):
super(inputform,self).__init__(*args,**kwargs)
self.fields['regionlist'] = forms.ModelChoiceField(queryset=anothermodel.objects.values('Region').distinct())
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render,render_to_response,get_object_or_404
from inputform.forms import inputform
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def input(request):
if request.method == 'POST':
form = inputform(request.POST)
if form.is_valid():
return HttpResponseRedirect('templates/About')
else:
form = inputform()
return render_to_response('inputform.html', {
'form': form,
})
Part of html
<body>
<script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<form action="" method="post">{% csrf_token %}
{{ form.regionlist }}
{% for region in form.regionlist.choices %}
<option value="{{ val }}" {% ifequal data.val val %}selected {% endifequal %}>
{% endfor %}
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from metrics import views
from django.views.generic.list import ListView
from django.views.generic import TemplateView
from django.conf import settings
from django.conf.urls.static import static
from inputform.views import input,ifglobal
admin.autodiscover()
urlpatterns = patterns('',
url(r'^login/',include('login.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^input', 'inputform.views.inputform'),
)
The trackback
Traceback:
File "C:\Python27\lib\site-packages\django-1.8.3 py2.7.egg\django\core\handlers\base.py" in get_response
223. response = middleware_method(request, response)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\middleware\clickjacking.py" in process_response
31. if response.get('X-Frame-Options', None) is not None:
Exception Type: AttributeError at /input
Exception Value: 'inputform' object has no attribute 'get'
The error is indeed in your URLs. Your pattern is pointing at 'inputform.views.inputform', ie the form, not the view. It should be 'inputform.views.input'.

Problems with logging in/out standart django user using class-based views

I am trying to create simple application that allows just login existing user and logout if logged in.
views.py
from django.views.generic.edit import FormView
from django.views.generic import DetailView
from django.contrib.auth import logout
from django.contrib.auth.models import User
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponseRedirect
class UserDetailView( DetailView ):
model = User
template_name = "main/user_detail.html"
class UserLoginView( FormView ):
form_class = AuthenticationForm
success_url = reverse_lazy("UserDetails")
template_name = "main/user_form.html"
def logout_view(request):
logout(request)
return HttpResponseRedirect('/login/')
urls.py
from django.conf.urls import patterns, include, url
from main import views
urlpatterns = patterns('',),
url( r'users/(?P<pk>\d+)/', views.UserDetailView.as_view(), name="UserDetails"),
url( r"logout/", views.logout_view, name="UserLogOut" ),
url( r"login/", views.UserLoginView.as_view(), name="UserLogIn" ),
)
user_form.html
{% if user.is_authenticated %}
Logout
{{ user.username }}
{% else %}
<form method='post'> {% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type='submit' value='Submit'>
</form>
{% endif %}
I don't know why, but server returns this error
Request Method: POST
Request URL: http://0.0.0.0:9000/login/
Django Version: 1.6.5
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'UserDetails' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
What's wrong?
UPD
I've tried this dirty hack success_url = reverse_lazy("Main:UserDetails", kwargs={ 'pk':1 } ) just to check that it's working. I've also added
{% if user.is_authenticated %}
Hooray!
{% else %}
What the hell???
{% endif %}
to the user_detail.html and for some reason got What the hell??? instead of Hooray!
Why authentication form doesn't actually authenticates user?
I think the problem is in this statement
success_url = reverse_lazy("UserDetails")
You need to provide user pk to reverse_lazy args, because URL is in form "users/user_id/".
So it's impossible to find out correct success URL.
In this line in your urlconf
url( r'users/(?P<pk>\d+)/', views.UserDetailView.as_view(), name="UserDetails"),
you are defining the url for UserDetails as 'something/users/pk'. But then you are not supplying a pk argument to that url. That's why your error says that the reverse was not found, because it tries to find a pattern which has no arguments.
There are several ways to fix your error, but I think the best solution would be to make the pk argument optional, like this:
url( r'users(?:/(?P<pk>\d+))?/', views.UserDetailView.as_view(), name="UserDetails"),
Hope this helps.

Categories

Resources