I am building an ecommerce site. Everything works well, except the forms. When I try to post something, it returns me 405 method get not allowed. Why is it giving GET error when I am trying to do POST? It works on some forms, like for example checkout. But when I try to use contact form and press send axios.post(‘/api/v1/contacto/’, data) it gets me this error 405. BTW, when I am using this e-commerce running it on my local machine, it works well.
Here is my sites-available:
upstream ecologic_app_server {
server unix:/webapps/ecologic/backend/venv/run/gunicorn.sock fail_timeout=0;
}
server {
listen 8000;
listen [::]:8000;
server_name myiphere;
client_max_body_size 40M;
location / {
root /webapps/ecologic/frontend;
try_files $uri /index.html;
index index.html index.htm;
}
location /static/ {
root /webapps/ecologic/backend;
}
location /media/ {
root /webapps/ecologic/backend;
}
location /api/v1/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Host $http_host;
proxy_pass http://ecologic_app_server/api/v1/;
proxy_ssl_session_reuse off;
proxy_redirect off;
}
location /admin/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://ecologic_app_server/admin/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_redirect off;
}
}
This is my urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('contacto/', views.contact_form_post),
path('reclamo/', views.complaints_form_post),
]
Here is my code for contact form:
@api_view(['POST'])
def contact_form_post(request):
if request.method == "POST":
serializer = ContactForm(data=request.data)
if serializer.is_valid():
first_name = serializer.validated_data['first_name']
last_name = serializer.validated_data['last_name']
phone = serializer.validated_data['phone']
email = serializer.validated_data['email']
subject = serializer.validated_data['subject']
message = serializer.validated_data['message']
print(first_name, last_name, phone, email, subject, message)
context = {
'first_name': first_name,
'last_name': last_name,
'phone': phone,
'email': email,
'subject': subject,
'message': message
}
html = render_to_string('emails/contact.html', context)
text = render_to_string('emails/contact.txt', context)
recipient = MainSettings.objects.first().contact_email
send_mail(
subject,
message=text,
html_message=html,
from_email=settings.DEFAULT_FROM_EMAIL,
recipient_list=[recipient],
fail_silently=False,
# auth_user=None, auth_password=None, connection=None, html_message=None
)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
What could be the problem? Thank you.
2
Answers
I have found a solution for this case. For some reason, POST methods were not allowed even though you didn't have to log in o register to send a contact email. The settings.py of my Django backend app was good. I didn't specify there anything related to being authenticated. I was able to solve that by adding AllowAny to my views that use POST method. In your views.py first add:
Then, you add:
So, I am not sure why this is working that way. Even after that, I tried deleting it and it worked well without AllowAny.
I suppose that its an Nginx config problem.
This question is related and may help:
POST request not allowed – 405 Not Allowed – nginx, even with headers included
Regarding that it works on your local, please Dockerize your app.