I'm new to django and trying to use SP on my project, when I run this code it says Expected a Response, HttpResponse or HttpStreamingResponse to be returned from the view, but received a <class 'NoneType'>
views.py
#api_view(['POST'])
def saveitem(request):
if request.method == "POST":
if request.POST.get('office_id') and request.POST.get('sem'):
saverec = Insertserialize(data=request.data)
saverec.office_id = request.POST.get('office_id')
saverec.sem = request.POST.get('sem')
cursor = connection.cursor()
cursor.execute("select add_clearance_item('"+saverec.office_id+"','"+saverec.sem+"')")
return Response(saverec.data, status=status.HTTP_201_CREATED)
serializers.py
class Insertserialize(serializers.ModelSerializer):
class Meta:
model = ClearanceInsert
fields = [
'office_id',
'sem',
]
Related
I am building an API for users info data
I want to make that when the POST request, execute function "create", "update"
if from POST request user exists:
update (full_name, function, department, logon, system, lic_type )
if from POST request user doesn't exist:
create (user, full_name, function, department, logon, system, lic_type )
models.py
from django.db import models
class Users(models.Model):
user = models.CharField(max_length=50,blank=True, null=True)
full_name = models.CharField(max_length=200, blank=True, null=True)
function = models.CharField(max_length=300,blank=True, null=True)
department = models.CharField(max_length=300,blank=True, null=True)
logon = models.DateTimeField(blank=True, null=True)
system = models.CharField(max_length=300,blank=True, null=True)
lic_type = models.CharField(max_length=300,blank=True, null=True)
serizlizers.py
from rest_framework import serializers
from .models import Users
class UsersSerializer(serializers.ModelSerializer):
logon = serializers.DateTimeField(input_formats=settings.DATE_INPUT_FORMATS)
class Meta:
model = Users
# fields = '__all__'
fields = ['user', 'full_name', 'function', 'department', 'logon', 'system', 'lic_type']
views.py
from django.http.response import JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework import status
from .models import Users
from .serializers import UsersSerializer
from rest_framework.decorators import api_view, authentication_classes
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
from rest_framework.authentication import BasicAuthentication
#csrf_exempt
#api_view(['GET', 'POST'])
#authentication_classes([BasicAuthentication])
def users_list(request):
if request.method == 'GET':
users = Users.objects.all()
user = request.GET.get('user', None)
if user is not None:
users = users.filter(user__icontains=user)
users_serializer = UsersSerializer(users, many=True)
return JsonResponse(users_serializer.data, safe=False)
elif request.method == 'POST':
users_data = JSONParser().parse(request)
users_serializer = UsersSerializer(data=users_data, many=True)
if users_serializer.is_valid():
users_serializer.save()
return Response(users_serializer.data, status=status.HTTP_201_CREATED)
return Response(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('users/', views.users_list),
]
I could do like this, when POST request delete all from database and create data from POST request
elif request.method == 'POST':
users = Users.objects.all()
users.delete()
users_data = JSONParser().parse(request)
users_serializer = UsersSerializer(data=users_data, many=True)
if users_serializer.is_valid():
users_serializer.save()
return Response(users_serializer.data, status=status.HTTP_201_CREATED)
return Response(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
but instead I want to make update_or_create()
I tried like so, but this only creates empty row in database
user_name = request.POST.get('user')
user, created = Users.objects.update_or_create(user = user_name)
user.full_name = request.POST.get('full_name')
user.function = request.POST.get('function')
user.department = request.POST.get('department')
user.logon = request.POST.get('logon')
user.system = request.POST.get('system')
user.lic_type = request.POST.get('lic_type')
user.save()
return Response(user, status=status.HTTP_201_CREATED)
thanks for any help
The best way is when a POST is there, you first retrieve the item from the database (using django's utility get_object_or_404) and have restframework update all fields you set as non-readonly in the serializer.
Example:
# on top import
from django.shortcuts import get_object_or_404
....
elif request.method == 'POST':
# add here the query you determine is user already exists, usually a unique ID or UUID
user_object = get_object_or_404(Users, id=request.data.get('id'))
users_data = JSONParser().parse(request)
users_serializer = UsersSerializer(user_object, data=users_data, many=True)
if users_serializer.is_valid():
users_serializer.save()
return Response(users_serializer.data, status=status.HTTP_201_CREATED)
return Response(users_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Something like this ought to work. You still need to tweak it a little the get object
New to Django and DRF, I have a method in the model properties which accept arguments. I have managed to call it successful though a serializer class with default paramenters and getting a JSON response. My problem is I can't pass argument to that function named balance. I have successful pass my argument from view to serializer class but from serializer to model that where I have failed. I thought will be appreciated.
model.py
class Item(models.Model):
entered_by = models.ForeignKey(User, on_delete=models.PROTECT)
name = models.CharField(max_length=50, blank=True)
#property
def balance(self, stock_type='Retail'):
stock = Stock.objects.filter(item=self, type=stock_type, status='InStock').aggregate(models.Sum('quantity')).get('quantity__sum')
return stock or 0
views.py
def getItemInfo(request):
if request.is_ajax and request.method == "GET":
id = request.GET.get("item_id", None)
sell_type = request.GET.get("sell_type", None)
item = Item.objects.get(id=id)
if item:
serializer = ItemSerializer(item, context={'sell_type':sell_type})
return JsonResponse(serializer.data, status = 200, safe=False)
else:
return JsonResponse({"data":False}, status = 400)
serializer.py
from rest_framework import serializers
from .models import Item
class ItemSerializer(serializers.ModelSerializer):
balance = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ('entered_by', 'name', 'balance', 'sell_mode')
def get_balance(self, object):
sell_type = self.context.get("sell_type")
if sell_type:
return object.balance(sell_type)
return object.balance
The error I'm getting
'int' object is not callable
#property couldn't be called. So I made member variable and setter (with calculation) methods in Item model, then make sure setter method will be called in get_balance serializer method, just before returning balance.
Django ORM model itself is just a class; you can do anything class could, not just only linking with ORM.
My Code:
models.py
from django.db import models
from django.contrib.auth.models import User
class Item(models.Model):
entered_by = models.ForeignKey(User, on_delete=models.PROTECT)
name = models.CharField(max_length=50, blank=True)
_balance = 0
def calculate_balance(self, stock_type='Retail'):
stock = Stock.objects.filter(item=self, type=stock_type, status='InStock').aggregate(
models.Sum('quantity')).get('quantity__sum')
self._balance = stock or 0
#property
def balance(self):
return self._balance
serializer.py
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Item
class ItemSerializer(serializers.ModelSerializer):
balance = serializers.SerializerMethodField()
class Meta:
model = Item
fields = ('entered_by', 'name', 'balance')
def get_balance(self, object):
sell_type = self.context.get("sell_type")
if sell_type:
object.calculate_balance(sell_type)
return object.balance
views.py
from .models import Item
from .serializer import ItemSerializer
from django.http.response import JsonResponse
def getItemInfo(request):
if request.is_ajax and request.method == "GET":
id = request.GET.get("item_id", None)
if id is None:
return JsonResponse({"data": False}, status=400)
sell_type = request.GET.get("sell_type", None)
try:
item = Item.objects.get(id=id)
serializer = ItemSerializer(item, context={'sell_type': sell_type})
return JsonResponse(serializer.data, status=200, safe=False)
except Item.DoesNotExist:
return JsonResponse({"data": False}, status=400)
The article serializer:
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model=Article
fields='__all__'
settings:
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
model:
class Article(models.Model):
title = models.CharField(max_length=50)
author = models.CharField(max_length=50)
email=models.EmailField()
date=models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
view function:
def article_list(request):
if request.method== 'GET':
article =Article.objects.all()
serializer = ArticleSerializer(article,many=True)
return JsonResponse(serializer.data,safe=False)
if request.method == 'POST':
data = JSONParser.parse(request)
serializer = ArticleSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data,status=201)
return JsonResponse(serializer.errors,status=400)
i just created a simple serializer but whenever i try to get the response it says that the ArticleSerializer i created has no attribute 'get'.
Error
Pass request.data to the serializer. You are parsing the whole request object and passing that instead of the required data.
...
if request.method == 'POST':
serializer = ArticleSerializer(data=request.data)
I am following this solution on how to get specific fields from a django model:
Select specific fields in Django get_object_or_404
from django.core import serializers as djangoserializer # module 'rest_framework.serializers' has no attribute 'serialize'
class ProjectDetailApiView(APIView):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, slug=None, format=None):
project_instance = get_object_or_404(Project.objects.only('project_title', 'project_post'), slug=slug)
data = djangoserializer.serialize('json', [ project_instance, ], fields=('project_title','project_post'))
user = self.request.user
updated = False
viewed = False
if not user in project_instance.project_views.all():
viewed = True
project_instance.project_views.add(user)
updated = True
data = {
"project": data,
"updated":updated,
"viewed":viewed
}
return Response(data)
Output:
{
"project": "[{\"model\": \"webdata.project\", \"pk\": 4, \"fields\": {\"project_title\": \"Project 4\", \"project_post\": \"Blabla\"}}]",
"updated": true,
"viewed": false
}
Desired Output:
{
"project_title": "Project 4",
"project_post": "Blabla",
"updated": true,
"viewed": false
}
Thank you
Use DRF's Serializer instead of Django's built-in serializer.
# serializers.py
from rest_framework import serializers
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ('project_title', 'project_post', 'updated', 'viewed')
# views.py
class ProjectDetailApiView(APIView):
authentication_classes = (authentication.SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, slug=None, format=None):
project_instance = get_object_or_404(Project, slug=slug)
serializer = ProjectSerializer(project_instance)
return Response(serializer.data)
The serialization of regular dictionaries is very good in python.
So instead of configuring the serializer - why not just create a python dictionary with the desired data? (That's how I do it for simple things that I need only in one place.)
data = {
"project_title": project_instance.project_title,
"project_post": project_instance.project_post,
"updated":updated,
"viewed":viewed
}
return JSONResponse(data)
You haven't posted the Project model, I'm just supposing from the serializer config that the fields are named project_title and project_post.
This will return a response with status 200, mimetype application/json and the data dict as valid JSON.
I am pretty new to Django rest-framework and trying to render a simple JSON view not based on the model. I could not figure out how to do this since all of the examples involves rendering JSON from the Model classes. Below is the simple example what I was trying to do.
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
class Comment(object):
def __init__(self, email, content, created=None):
self.email = email
self.content = content
self.created = created or datetime.now()
def comment_view(request):
comment = Comment(email='leila#example.com', content='foo bar')
serializer = CommentSerializer(comment)
json = JSONRenderer().render(serializer.data)
return json
You can use it like here:
from rest_framework.decorators import api_view
from rest_framework.response import Response
#api_view()
def comment_view(request):
comment = Comment(email='leila#example.com', content='foo bar')
serializer = CommentSerializer(comment)
return Response(serializer.data)
Finally don't forget to put it in the urls.py:
urlpatterns = [
path('comments/', comment_view, name='comment-view'),
]