Suddenly my api_view is not defined. Why? - python

I am making a webpage using React frontend and Django backend. I have trouble running my backend because things supposedly aren't defined. E.g. I get this message when trying to run
python manage.py makemigrations
getting error,
name 'api_view' is not defined
What can I do to fix it?
from django.http import HttpResponse
from .serializers import UserSerializer
def homePageView(request):
return HttpResponse('Hello, World!')
#
#api_view(['POST'])
def createUserView(request):
# Create a new user
if request.method == 'POST':
# Create serializer with data from new user object
serializer = UserSerializer(data=request.data) #datafeltet inneholder json fra frontend, se eks. nederst
if serializer.is_valid():
# Save user
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#return HttpResponse('User')

You need to import from api_view decorator as,
from rest_framework.decorators import api_view
Check that you are using correct virtual enviornment.
And make sure that rest_framework is installed or not using pip freeze

Related

i'm not able to understand why i have to restart the server to see the changes made by a Put request (django rest framework)

The put request is working, but if i want to see the post updated i have to restart the server.
This is the view function:
from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view
from blog.models import Post
from .serializers import PostSerializer
from django.contrib.auth.models import User
#api_view(['PUT'])
def api_update_post_view(request, Slug):
try:
blog_post = Post.objects.get(slug=Slug)
except Post.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = PostSerializer(blog_post, data=request.data, partial=True)
data = {}
if serializer.is_valid():
serializer.save()
data['succes'] = 'update successful'
return Response(data=data)
return Response(serializer.errors, status.HTTP_400_BAD_REQUEST)
I didn't see any special features in your PUT method. So, I suggest you to use ModelViewSet instead of creating a basic PUT method yourself. ModelViewSet will generate basic CRUD operations for you automatically.
Here is the official docs. It should be no problem after you use the ModelViewSet.

How to use Last-Modified header with Django Rest Framework ViewSet?

Let's say I have following Django Rest Framework's ViewSet:
from django.contrib.auth import get_user_model
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
class SubscriptionViewSet(ViewSet):
def list(self, request):
data = {'user_count': get_user_model().objects.count()}
return Response(data)
How to use it together with last_modified decorator from Django? Or how to implement such functionality?
I checked package mentioned by #Makarand Bauskar. However I wasn't satisfied. It's not active and it uses custom way how to work/deal with Last-Modified header. So I decided to create new package django-rest-framework-condition that does:
Re-uses implementation from Django
it will get fixes from Django
you can use it same way as described in Django's docs
Provides both #last_modified and #etag decorator
To install it:
pip install django-rest-framework-condition
Usage:
from django.contrib.auth import get_user_model
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework_condition import last_modified
def my_last_modified(request, *args, **kwargs):
return datetime(2019, 1, 1)
class SubscriptionViewSet(ViewSet):
#last_modified(my_last_modified)
def list(self, request):
data = {'user_count': get_user_model().objects.count()}
return Response(data)
#jozo,
You can check the https://github.com/jatir/django-rest-framework-last-modified django app to use the Last-Modified
Edit:
you can check the example in the test directory
https://github.com/jatir/django-rest-framework-last-modified/blob/master/tests/views.py#L14

Django Rest Framework get serializer of different model?

I have a method in one of my viewsets:
Endpoint: /api/game/{id}/sessions:
from .serializers import GameSerializer
from .models import Game
from gamesessions.models import GameSession
from gamesessions.serializers import GameSessionSerializer
from gamesessions.viewsets import GameSessionViewSet
#action(methods=['get'], detail=True)
def sessions(self, request, **id):
game = self.get_object()
sessions = []
for session in GameSession.objects.filter(game=game.id):
sessions.append(session)
serializer = GameSessionViewSet.get_serializer(sessions, many=True)
return Response(serializer.data)
But I'm getting an error because I can't figure out where the get_serializer method comes from and/or how to implement it externally.
I need to get the serializer of the session model. I can generate the list of sessions just fine, but it says the object is not JSON serializable, which is what DRF is supposed to handle.
So I just need to know what do I import to get the seralizer from the other class?
Maybe you can try, to use the serializer directly with the name like this:
serializer = GameSessionSerializer(sessions, many=True)

POST JSON request data dropped/disappear when sending to djangorestframework

I get stuck on making a simple RESTful test using django-rest-framework. I am new beginner to this. Please help. Thanks in advance!
version:
django >= 1.9
djangorestframework 3.3.3
python 3.4.3
POST request from terminal
curl -H "Content-Type: application/json" -X POST -d '{"title":"xyz","desc":"xyz"}' http://localhost:3000/api/test/
django's settings.py
INSTALLED_APP = {
'app',
'rest_framework',
#....skip to keep it short
}
# did not set anything
<!-- language-all: lang-python -->
REST_FRAMEWORK = {
}
# models.py
class Test(object):
def __init__(self, title, desc):
self.title = title
self.desc = desc
serializers.py
from rest_framework import serializers
class TestSerializer(serializers.Serializer):
title = serializers.CharField()
desc = serializers.CharField(max_length=200)
class Meta:
model = Test
fields = ('title', 'desc')
views.py
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
#csrf_exempt
class TestView(APIView):
def get(self, request, format=None):
# 1. we use NoSQL, is the following line still work?
# testItems = Test.objects.all()
serializer = SnippetSerializer(testItems, many=True)
return Response(serializer.data)
def post(self, request, format=None):
# 2. Unable to get any json string in request object or request.data at all!
# 3. The entire json seems disappear and get dropped
serializer = TestSerializer(data=request.data)
if serializer.is_valid():
# 4. can save() be overrided and do custom implementation? How?
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns(
'app',
url(r'^api/business/$', app.views.TestView.as_view()),
)
My Questions:
we use NoSQL, is the following line still work?
testItems = Test.objects.all()
empty request.data in POST JSON request.
Unable to get any json string in request object
or request.data at all! The entire json seems disappear and get
dropped. Tried to use Fiddler/Postman capture and ensure JSON did sent out
Can save() be overrided and do custom implementation? How?
I don't know about NOSQL but you can test it on shell. I'm guessing probably it works.
About request.data error; request.data is only used for file upload with django rest framework. When you post a json, it's in the body of the request. What you should do is something like this in your view:
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import json
#csrf_exempt
class TestView(APIView):
# your get request here.
def post(self, request, format=None):
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
# Now, your json content is stores in data as a dictionary.
serializer = TestSerializer(data=request.data)
if serializer.is_valid():
# 4. can save() be overrided and do custom implementation? How?
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
FYI,I use serializers for just creating json, I don't use it to create object. Therefore, I'm not sure if this version %100 works or not. But I'm pretty sure that 2 line I've added turns JSON to dictionary. If serializer accepts dictionary as a data, it'll work.

Django rest framework and python3.5 OrderedDict mutated during iteration

I use Django rest framework and python3.5. Earlier I had another version of python and everything was going right. When I want to get some information from server with URL for example like:
"http://127.0.0.1:8000/api/companies"
I'm getting error:
"OrderedDict mutated during iteration"
.
In views.py I have:
from django.shortcuts import render
from companies.models import Companies
from companies.serializers import CompaniesSerializer
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer
from rest_framework import status
class CompaniesList(generics.ListCreateAPIView):
queryset = Companies.objects.all()
serializer_class = CompaniesSerializer
class CompaniesDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Companies.objects.all()
serializer_class = CompaniesSerializer
What should I do to make it working? Where is something mutating the dict?
I don't know why using ListCreateApiView is mutating dict, but I changed class into function like :
#api_view(['GET'])
def CompaniesList(request):
if request.method == 'GET':
companies = Companies.objects.all()
serializer = CompaniesSerializer(companies, many=True)
return Response(serializer.data)
and now it's working...

Categories