0

I was wondering if anyone can help, I am creating a rest framework with django and react. The problem is when I go to create a new product I get the following error:

Method "POST" not allowed. in my product_views.py I have the following:

@api_view(['POST'])
@permission_classes([IsAdminUser])
def createProduct(request):
   user = request.user
   product = Product.objects.create(
       user=user,
       name='Sample Name',
       price=0,
       brand='Sample Brand',
       countInStock=0,
       category='Sample Category',
       description=''
       )

In my product_urls.py I have the following:

from django.urls import path
from base.views import product_views as views

    urlpatterns = [

    path('', views.getProducts, name="products"),
    path('<str:pk>/', views.getProduct, name="product"),
    path('create/', views.createProduct, name="product-create"),
    path('update/<str:pk>/', views.updateProduct, name="product-update"),
    path('delete/<str:pk>/', views.deleteProduct, name="product-delete"),
 ]

My settings.py is set to JWT (simple):

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework_simplejwt.authentication.JWTAuthentication',
   )
}

from datetime import timedelta

SIMPLE_JWT = {
 'ACCESS_TOKEN_LIFETIME': timedelta(days=30),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': False,

'ALGORITHM': 'HS256',
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,

'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',

'JTI_CLAIM': 'jti',

'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

in my react productListScreen.js I have:

    import React, { useState, useEffect } from 'react'
    import { LinkContainer } from 'react-router-bootstrap'
    import { Table, Button, Row, Col } from 'react-bootstrap'
    import { useDispatch, useSelector } from 'react-redux'
    import Loader from '../components/Loader'
    import Message from '../components/Message'
    import Paginate from '../components/Paginate'
    import { listProducts, deleteProduct, createProduct } from '../actions/productActions'
    import { PRODUCT_CREATE_RESET } from '../constants/productConstants'

    function ProductListScreen({ history, match }) {

        const dispatch = useDispatch()

        const productList = useSelector(state => state.productList)
        const { loading, error, products, pages, page } = productList

        const productDelete = useSelector(state => state.productDelete)
        const { loading: loadingDelete, error: errorDelete, success: successDelete } = productDelete

        const productCreate = useSelector(state => state.productCreate)
        const { loading: loadingCreate, error: errorCreate, success: successCreate, product: createdProduct } = productCreate


        const userLogin = useSelector(state => state.userLogin)
        const { userInfo } = userLogin

        let keyword = history.location.search
        useEffect(() => {
            dispatch({ type: PRODUCT_CREATE_RESET })

            if (!userInfo.isAdmin) {
                history.push('/login')
            }

            if (successCreate) {
                history.push(`/admin/product/${createdProduct._id}/edit`)
            } else {
                dispatch(listProducts(keyword))
            }

        }, [dispatch, history, userInfo, successDelete, successCreate, createdProduct, keyword])


        const deleteHandler = (id) => {

            if (window.confirm('Are you sure you want to delete this product?')) {
                dispatch(deleteProduct(id))
            }
        }

        const createProductHandler = () => {
            dispatch(createProduct())
        }

        return (
            <div>
                <Row className='align-items-center'>
                    <Col>
                        <h1>Products</h1>
                    </Col>

                    <Col className='text-right'>
                        <Button className='my-3' onClick={createProductHandler}>
                            <i className='fas fa-plus'></i> Create Product
                        </Button>
                    </Col>
                </Row>

                {loadingDelete && <Loader />}
                {errorDelete && <Message variant='danger'>{errorDelete}</Message>}


                {loadingCreate && <Loader />}
                {errorCreate && <Message variant='danger'>{errorCreate}</Message>}

                {loading
                    ? (<Loader />)
                    : error
                        ? (<Message variant='danger'>{error}</Message>)
                        : (
                            <div>
                                <Table striped bordered hover responsive className='table-sm'>
                                    <thead>
                                        <tr>
                                            <th>ID</th>
                                            <th>NAME</th>
                                            <th>PRICE</th>
                                            <th>CATEGORY</th>
                                            <th>BRAND</th>
                                            <th></th>
                                        </tr>
                                    </thead>

                                    <tbody>
                                        {products.map(product => (
                                            <tr key={product._id}>
                                                <td>{product._id}</td>
                                                <td>{product.name}</td>
                                                <td>${product.price}</td>
                                                <td>{product.category}</td>
                                                <td>{product.brand}</td>

                                                <td>
                                                    <LinkContainer to={`/admin/product/${product._id}/edit`}>
                                                        <Button variant='light' className='btn-sm'>
                                                            <i className='fas fa-edit'></i>
                                                        </Button>
                                                    </LinkContainer>

                                                    <Button variant='danger' className='btn-sm' onClick={() => deleteHandler(product._id)}>
                                                        <i className='fas fa-trash'></i>
                                                    </Button>
                                                </td>
                                            </tr>
                                        ))}
                                    </tbody>
                                </Table>
                                
                            </div>
                        )}
            </div>
        )
    }

    export default ProductListScreen

Can anyone tell me why I am getting the error message? Any help would be appreciated.

Ankit Tiwari
  • 4,438
  • 4
  • 14
  • 41

1 Answers1

0

Maybe it is the same case as this one.

405 "Method POST is not allowed" in Django REST framework.

Dharman
  • 30,962
  • 25
  • 85
  • 135
sirius9515
  • 309
  • 1
  • 8
  • I did try that before but to no avail. Still scratching my head?? – Who Me Dunno Mate Jun 24 '21 at 10:26
  • so as far as I can see /api/products/create/:1 Failed to load resource: the server responded with a status of 405 (Method Not Allowed), in redux in my tree i get: loading(pin):true => false error(pin):'Method "POST" not allowed.' – Who Me Dunno Mate Jun 24 '21 at 10:37
  • url is not defined correctly. it is defined as "create/" and should be in "create//" format or "create". So url dismatch. I think the ref link actually contains contents similar to your case. – sirius9515 Jun 24 '21 at 11:09
  • Yep, what you said there makes sense but I think the root of the problem is to do with authentication, postman seems to return my headers with auth token but local host locks me out with not authorised and thus method post not allowed – Who Me Dunno Mate Jun 24 '21 at 15:10