0

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.

Ivan Stepanchuk
  • 159
  • 1
  • 9

2 Answers2

1

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.

alfawal
  • 37
  • 1
  • 7
0

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:

from rest_framework.permissions import AllowAny

Then, you add:

@api_view(['POST'])
@permission_classes([AllowAny])
def contact(request):

So, I am not sure why this is working that way. Even after that, I tried deleting it and it worked well without AllowAny.

Ivan Stepanchuk
  • 159
  • 1
  • 9