Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework - CreateAPIView doesn't let use POST method

I try to create a view, that will accept POST requests and create new instances of my model(see bottom of post). I follow this tutorial. The problem is that when I access URL associated with view, which inherits from CreateAPIView I dont see a form in html representation of API for creation of new instances and I also see that it accepts GET requests, not POST as it mentioned in documentation.

Page looks like this

enter image description here

My views.py

from django.shortcuts import render
from rest_framework.generics import ListAPIView, CreateAPIView
from datingapp.models import Profile
from .serializers import ProfileSerializer, ProfileCreateSerializer

class ProfilesAPIView(ListAPIView):
  queryset = Profile.objects.all()
  serializer_class = ProfileSerializer

class ProfileCreateAPIView(CreateAPIView):
  queryset = Profile.objects.all()
  serializer_class = ProfileCreateSerializer

My urls.py

from django.conf.urls import url
from django.contrib import admin

from datingapp.views import ProfilesAPIView, ProfileCreateAPIView

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'api/profiles/', ProfilesAPIView.as_view(), name='list'),
   url(r'api/profiles/create/$', ProfileCreateAPIView.as_view(), name='create')
   ]

My serializers.py

from rest_framework.serializers import ModelSerializer
from datingapp.models import Profile

class ProfileSerializer(ModelSerializer):
  class Meta:
    model = Profile
    fields = [
        'name',
        'age',
        'heigth'
        'location',
    ]

class ProfileCreateSerializer(ModelSerializer):
  class Meta:
    model = Profile
    fields = [
        'name',
        'age',
        'heigth'
        'location',
    ]  

In my settings.py I have crispy_forms installed.

What am I doing wrong ?

UPD: here is what I want to achieve

enter image description here

As you see there is a form and it accepts only POST and also says that GET is not allowed

like image 793
Alexey K Avatar asked Jun 03 '16 16:06

Alexey K


People also ask

How do you pass extra context data to Serializers in Django REST framework?

In function-based views, we can pass extra context to serializer with “context” parameter with a dictionary. To access the extra context data inside the serializer we can simply access it with “self. context”. From example, to get “exclude_email_list” we just used code 'exclude_email_list = self.

Why use Django REST framework instead of django?

Its main benefit is that it makes serialization much easier. Django REST framework is based on Django's class-based views, so it's an excellent option if you're familiar with Django. It adopts implementations like class-based views, forms, model validator, QuerySet, and more.


2 Answers

The problem is in your router. The first pattern matches both api/profiles/ and api/profiles/create/ so the second one will never be evaluated. You are seeing the ProfilesAPIView instead of the create view.

 url(r'api/profiles/', ProfilesAPIView.as_view(), name='list'),
 url(r'api/profiles/create/$', ProfileCreateAPIView.as_view(), name='create')

To fix it, either swap the order of the urls, or add a $ to the end of the first pattern. r'api/profiles/$'

like image 64
Håken Lid Avatar answered Jan 04 '23 06:01

Håken Lid


I was following a tutorial and had a similar problem. Probably I was not following the same version of Django Rest Framework and they had changes. But I solved this problem doing this.

class AssetBundleList(generics.ListAPIView):

to

class AssetBundleList(generics.ListCreateAPIView):

Hope this helps someone.

like image 21
Олег Avatar answered Jan 04 '23 05:01

Олег