How to send POST request to Django REST API using python requests - python

I have a simple rest api which I want to send a post request to using requests.
My url pattern is this:
url(r'^$', views.ProductList.as_view())
Inside my view I have:
class ProductList(generics.ListAPIView):
serializer_class = ProductSerializer
def post(self, request, format=None):
print('THIS IS A POST REQUEST')
queryset = [product.name for product in Product.objects.all()]
return Response(queryset)
And I am trying to send a post request using:
response = requests.post('http://127.0.0.1:8080/')
However this returns a 403, and the print statement isn't printed. I have done some research and I think it may have something to do with the CSRF token not being there but i'm not to sure how to add that. Does anybody know how I can get the post request to work?
I'm using python 3.6.3 and Django 1.10

ListAPIView is meant for only listing your products hence the POST requests are forbidden.
ListAPIView
Used for read-only endpoints to represent a collection of model instances.
taken from Django Rest Framework documentation
You should use ListCreateAPIView:
class ProductList(generics.ListCreateAPIView):
"""
List all products or create a product.
"""
queryset = Product.objects.all()
serializer_class = ProductSerializer

Related

Django rest + React front

Currently, I am working with a group to try to create a website with a functional Django backend and a React frontend. We are using a user view set
class UserViewset(viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin):
permissions_classes = (permissions.AllowAny,)
serializer_class = UserSerializer
queryset = User.objects.all()
This is where I am stuck, I haven't used viewsets or serializers before and I am at an impasse on where to go from here. I was hoping to get some clarification of how to add in a create/register user plus login and logout functions so that we can start messing with our api. Any help would be appreciated.
For Login you can use the following code in urls.py-:
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns=[
//your urls
path("api/login/",obtain_auth_token,name="auth_user_login"),]//<-- include this line
]
You can use this endpoint to authenticate using token authentication.
For this you need to do some modification in settings.py file
INSTALLED_APPS=[
//Your existing apps
'rest_framework.authtoken'
]
REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":(
"rest_framework.authentication.TokenAuthentication",
"rest_framework.authentication.SessionAuthentication"
),
}
In react you can send post request to this endpoint with username and password for login. This will send back authentication token which will be used in next requests that needs authentication.

Django Rest Framework how to disable authentication and authorization

I am trying to build a system in Django without using any of its batteries -- auth, admin etc. The system uses the Django rest framework for the API.
However, when I try to request to an API, I keep getting this error:
Model class django.contrib.auth.models.Permission doesn't declare an explicit
app_label and isn't in an application in INSTALLED_APPS.
I do not want to use django.contrib.auth at all. I did the following inside my DRF API View class:
class NewsPostView(APIView):
permission_classes = None
def get(self, request, format=None):
posts = NewsPost.objects.all()
serializer = NewsPostSerializer(posts, many=True)
return Response([])
However, I am still getting the same error. How can I disable auth from DRF?
I have solved my issue. After #Linovia's response, I checked the docs etc of DRF and changed the following properties:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [],
'DEFAULT_PERMISSION_CLASSES': [],
'UNAUTHENTICATED_USER': None,
}
And everything worked.
Use AllowAny instead of None. And also your response seems to be returning empty list. use serializer.data for retrieving data
from rest_framework.permissions import AllowAny
class NewsPostView(APIView):
permission_classes = (AllowAny,)
def get(self, request, format=None):
posts = NewsPost.objects.all()
serializer = NewsPostSerializer(posts, many=True)
return Response(data=serializer.data)
Make sure you don't use rest_framework.urls and that your settings has:
'DEFAULT_AUTHENTICATION_CLASSES': tuple(),
as well as your views.
With some luck, you won't have the authentication imported through another import.

Can I use both Django and Rest Framework views in a single project?

I want to add some REST API views to an existing Django project, which uses vanilla Django views. For that I'd like to use the REST Framework. I wonder if I can I mix Django and RF views in a single project and what pitfalls this might have (e.g. with authentication).
Yes you can surely use both of them at the same time, there shouldn't be any issue. Typically the Django views use SessionAuthentication, adn you will use DRF using TokenAuthentication -- best practice is to add both Session and Token authentication to the authentication_classes in the DRF views - that way you can use the browsable api pages to browse the apis once you have signed in via password (session authentication) as well
class GenericViewTest(SuperuserRequiredMixin, View):
def get(self, request, *args, **kwargs):
return HttpResponse("Test")
class PostTrackingCode(CreateAPIView):
"""
"""
authentication_classes = (SessionAuthentication, TokenAuthentication) ----> note this
permission_classes = (permissions.IsAuthenticated,)
serializer_class = TrackingInfoWriteSerializer
model = TrackingInfo

Djangorest framework same Generic Create View with GET and POST

I'm using a Generic CreateAPIView to save a model in the database. Here's my code:
class AppointmentCreateAPIView(generics.CreateAPIView):
permission_classes = (AppointmentCreatePermission,)
queryset = Appointment.objects.all()
serializer_class = AppointmentSerializer
And in my urls.py file, I have this:
urlpatterns[
url(r'^appointments/create', AppointmentCreateAPIView.as_view()),
]
This url obviously supports the POST operation. However, I want to use this same url to handle a GET request, which would fetch the data necessary to populate the appointment creation form. I understand that I can use separate urls for get and post, but that's not what I'm looking for. Is it possible that I keep the same url, but with different HTTP Verb, the view would be able to handle both GET and POST request?
You can do this by manually adding get method to your view, it would look something like this. Code below probably will not work, but will give you general idea.
from rest_framework.response import Response
class AppointmentCreateAPIView(generics.CreateAPIView):
permission_classes = (AppointmentCreatePermission,)
queryset = Appointment.objects.all()
serializer_class = AppointmentSerializer
def get(self, request, *args, **kwargs):
serializer = AppointmentSerializer({your_data})
return Response(serializer.data)

Django REST error returning a list of objects

I am using the Django REST framework in order to implement a game server for an android game. I have written a class, that is derived from GenericAPIView to handle a specific Http Post request. I want the request to return a list of some objects, that were previously queried from the database.
My code looks like this:
class NewGameView(GenericAPIView):
serializer_class=NewGameRequestSerializer
def post(self, request, format=None):
serializer = NewGameRequestSerializer(data=request.DATA)
if serializer.is_valid():
req=serializer.save()
mygamedata=...; # request game data objects
serializer = MyGameDataSerializer(mygamedata, many=True)
return Response(serializer.data,status=status.HTTP_201_CREATED)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
When I access this view via curl, everything works as expected. However, when I submit using the Django generated "browsable api" form, I am receiving a
'ListSerializer' object is not iterable
error during "template rendering". If I derive my class from APIView instead, the error does not occur, but Django will not display the forms anymore (for whatever reason).
Can anyone explain what is going on?
Thanks
You can just return a dictionary with the data you need.
class NewGameView(GenericAPIView):
serializer_class=NewGameRequestSerializer
def post(self, request, format=None):
serializer = NewGameRequestSerializer(data=request.DATA)
if serializer.is_valid():
req=serializer.save()
mygamedata=...; # request game data objects
data = {'game_name': mygame_object.name}
return Response(data,status=status.HTTP_201_CREATED)

Categories

Resources