I am using Postman to get my request. My GET and POST appear to be working fine. It's only when I go to update the data with PUT that its where I am running into the hiccup. Postman actually sends data back as if the object is being updated, but when I go to check via GET it's the same data as before. I have tried adding the hive data to the serializer.save, but it tells me I'm adding too many parameters.
models.py
class Inspection(models.Model):
hive = models.ForeignKey(Hive, on_delete=models.CASCADE)
user = models.ForeignKey(User,on_delete=models.CASCADE)
eggs = models.IntegerField()
larvae = models.IntegerField()
sealed_brood = models.IntegerField()
covered_bees = models.IntegerField()
nectar_honey = models.IntegerField()
pollen = models.IntegerField()
pest_spotted = models.CharField(max_length=200)
pest_action = models.CharField(max_length=200)
notes_concerns = models.CharField(max_length=300)
serializers.py
class InspectionSerializer(serializers.ModelSerializer):
class Meta:
model = Inspection
fields = ['id', 'eggs', 'larvae', 'sealed_brood', 'covered_bees', 'nectar_honey', 'nectar_honey', 'pollen', 'pest_spotted', 'pest_action', 'notes_concerns','user_id','hive','hive_id']
depth = 1
hive_id = serializers.IntegerField(write_only=True)
Views.py
#api_view(['GET', 'POST','PUT'])
#permission_classes([IsAuthenticated])
def inspection_details(request, pk):
hive = get_object_or_404(Hive, pk=pk)
inspection = Inspection.objects.filter(hive_id = hive.id, user=request.user)
if request.method == "GET":
serializer = InspectionSerializer(inspection, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
elif request.method == 'POST':
serializer = InspectionSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save(user=request.user)
return Response(serializer.data,status.HTTP_200_OK)
elif request.method == 'PUT':
serializer = InspectionSerializer(hive, data=request.data)
if serializer.is_valid(raise_exception=True):
serializer.save(user=request.user)
return Response(serializer.data, status=status.HTTP_200_OK)
I think the instance variable is not correct, it should be inspection not hive.
#api_view(['GET', 'POST', 'PUT'])
#permission_classes([IsAuthenticated])
def inspection_details(request, pk):
hive = get_object_or_404(Hive, pk=pk)
inspection = Inspection.objects.filter(hive_id = hive.id, user=request.user)
...
elif request.method == 'PUT':
serializer = InspectionSerializer(inspection, data=request.data) # here
if serializer.is_valid(raise_exception=True):
serializer.save(user=request.user)
return Response(serializer.data, status=status.HTTP_200_OK)
First of all don't use if clause for is_valid. it raise exception anyway so if is not needed.
Next you need to update your serializer not saving it.
elif request.method == 'PUT':
serializer = InspectionSerializer(hive, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.update(object_to_update,serializer.validated_data)
# if you want to return updated serialized data :
updated_serializer = InspectionSerializer(object_to_update)
return Response(updated_serializer.data, status=status.HTTP_200_OK)
Related
can anyone help please, with DRF
according to POST request, I want to create(if not exists) or update() table
belows are my codes
model.py
class User1(models.Model):
user = models.CharField(max_length=10)
full_name = models.CharField(max_length=20)
logon_data = models.DateTimeField(blank=True, null=True)
serializer.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User1
fields = '__all__'
views.py
from .models import User1
from .serializers import UserSerializer
from rest_framework.response import Response
from rest_framework.decorators import api_view
#api_view(['GET', 'POST'])
def UserView(request):
if request.method == 'GET':
users = User1.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
elif request.method == 'POST':
users = User1.objects.all()
serializer = UserSerializer(data=request.data, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('users/', views.UserView),
]
when POST request, I want to check like this:
if user exists:
if user.full_name == request.fullname
update (user.logon_data)
save()
else:
update (user.full_name)
update (user.logon_data)
save()
else:
create(
user = request.user,
full_name = request.full_name,
logon_data = request.logon_date)
save()
POST request for JSON like this:
[
{
"user": "testuser1",
"full_name": "test user1",
"logon_data": "2022-10-19 09:37:26"
},
{
"user": "testuser2",
"full_name": "test user2",
"logon_data": "2022-10-20 07:02:06"
}
]
#api_view(['GET', 'POST'])
def UserView(request):
if request.method == 'GET':
users = User1.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = UserSerializer(data=request.data, many=True)
# if serializer validation fails, raises error by itself
serializer.is_valid(raise_exception=True)
for data in serializer.validated_data:
# checking if data exists else creating an object in User1 model
# user = data['user'] --> filter to check if that user exist
# defaults={'full_name': data['full_name'], 'logon_data': #data['logon_data']} --> value provided in defaults is used to update data in #model once the condition is met.
User1.objects.update_or_create(user=data['user'], defaults={'full_name': data['full_name'], 'logon_data': data['logon_data']})
return Response(serializer.data, status=201)
Try this update_or_create it will check based on request.user whether it exists in table or not
Also ensure that request.user is checked to user object if you want to check specific field then it should be request.user.user
User.objects.update_or_create(user=request.user.user, defaults={"full_name": request.full_name, "logon_date":request.logon_date})
I am trying to upload both text data and a file to django server using angular for the front-end,
here is my models in django
#models.py
class UploadChapter(models.Model):
chapter_number = models.CharField(max_length=50, choices=chapters)
chapter_file = models.FileField(upload_to="files")
student = models.ForeignKey(User,on_delete=models.CASCADE)
supervisor = models.ForeignKey(Supervisor, on_delete=models.CASCADE)
status = models.CharField(max_length=100, choices=status, default="Pending")
def __str__(self):
return f'{self.student} - {self.chapter_number}'
for the serializer I wrote this code
#serializers.py
class UploadChapterSerializer(serializers.ModelSerializer):
class Meta:
model = UploadChapter
fields = ['chapter_number', 'chapter_file', 'student', 'supervisor', 'status']
and for the views i wrote this code
#views.py
#csrf_exempt
def ChapterApi(request, id=0):
if request.method=='GET':
chapters=UploadChapter.objects.all()
chaptersSerializer=UploadChapterSerializer(chapters, many=True)
return JsonResponse(chaptersSerializer.data, safe=False)
elif request.method=='POST':
chaptersData=JSONParser().parse(request)
chaptersSerializer=UploadChapterSerializer(data=chaptersData)
if chaptersSerializer.is_valid():
chaptersSerializer.save()
return JsonResponse('Added Successfully', safe=False)
return JsonResponse('Failed', safe=False)
so am getting errors from the JSONParser and I really dont know how to do this, I need help please
I found an answer for myself, i wrote a class-based view instead of the function based, here is the code for it
class ChapterView(APIView):
parser_classes = (MultiPartParser, FormParser)
def post(self, request, *args, **kwargs):
chapter_serializer = UploadChapterSerializer(data=request.data)
if chapter_serializer.is_valid():
chapter_serializer.save()
return JsonResponse('Chapter Sent Successfully', safe=False)
else:
return JsonResponse('upload fail', safe=False)
def get(self, request):
chapter = UploadChapter.objects.all()
chapterSerializer = UploadChapterSerializer(chapter, many=True)
return JsonResponse(chapterSerializer.data, safe=False)
I tried many times, but I just register the last one
im my model
class PropertyImage(models.Model):
property = models.ForeignKey(Property, default=None, on_delete=models.CASCADE,)
images = models.ImageField(upload_to=upload, null=True, blank=True)
def __str__(self):
return str(self.images)
serializer
class PropertyImageSerializers (serializers.ModelSerializer):
class Meta:
model = PropertyImage
#fields =('name','')
fields = '__all__'
my class view handler the post request, I tried to user method FOR to loop all images and save
view
def post(self, request, *args, **kwargs):
property_id = request.data['property']
form_data = {}
for images in request.FILES.getlist('images'):
form_data['property']= property_id
form_data['images']=images
print(form_data)
serializer = PropertyImageSerializers(data=form_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
the for not give me the loop, does't matter how many images I send
I get this error message: AttributeError: 'PropertyImageSerializers'
object has no attribute 'property' but im my model you can see I have
the property
property is not an attribute of the PropertyImageSerializers class, that's why AttributeError
I think you will find your answer here
Update:
You can do it like this
def post(self, request, *args, **kwargs):
property_id = request.data['property']
form_data = {}
form_data['property']= property_id
success = True
response = []
for images in request.FILES.getlist('images'):
form_data['images']=images
print(form_data)
serializer = PropertyImageSerializers(data=form_data)
if serializer.is_valid():
serializer.save()
response.append(serializer.data)
else:
success = False
if success:
return Response(response, status=status.HTTP_201_CREATED)
return Response(response,status=status.HTTP_400_BAD_REQUEST)
I'm trying to learn DJango Rest so I made a litte test to see if I could obtain some things from the database, but I'm getting some problems.
Here's my models.py:
from django.db import models
# Create your models here.
class Stock(models.Model):
ticker = models.CharField(max_length=10)
open = models.FloatField()
close = models.FloatField()
volume = models.IntegerField()
def __str__(self):
return self.ticker
Here's my serializers.py:
from rest_framework import serializers
from .models import Stock
class StockSerializer(serializers.ModelSerializer):
ticker = serializers.CharField()
open = serializers.FloatField()
close = serializers.FloatField()
volume = serializers.IntegerField()
def create(self, validated_data):
return Stock.objects.check(**validated_data)
def update(self, instance, validated_data):
instance.ticker = validated_data.get('ticker', instance.ticket)
instance.open = validated_data.get('open', instance.open)
instance.close = validated_data.get('close', instance.close)
instance.volume = validated_data.get('volume', instance.volume)
instance.save()
return instance
class Meta:
model = Stock
fields = '__all__'
Here's my views.py:
from django.http import Http404
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Stock
from .serializers import StockSerializer
# List all stocks or create a new one
# stocks/
#api_view(['GET', 'POST'])
def stock_list(request, format=None):
if request.method == 'GET':
stocks = Stock.objects.all()
serializer = StockSerializer(stocks, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = StockSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#api_view(['GET', 'POST', 'DELETE'])
def stock_detail(request, pk, format=None):
try:
stock = Stock.objects.get(pk=pk)
except Stock.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = StockSerializer(stock)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = StockSerializer(stock, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
stock.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
And finally, here's my url.py:
from django.conf.urls import url
from django.contrib import admin
from rest_framework.urlpatterns import format_suffix_patterns
from companies import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^stocks/', views.stock_list),
url(r'^stocks/(?P<pk>[0-9]+)$', views.stock_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
I've been following this tutorial, but when it comes to the moment of making some requests (for this example I use this one: http http://127.0.0.1:8000/stocks/
I get this error message:
TypeError at /stocks/ stock_list() missing 1 required positional
argument: 'request'
I think that the problem is with the urls, but I'm not sure how to fix it.
Any ideas and some examples?
UPDATE: The problem was with the methods in view (they had an attibute self)
The general Get method works, but when I try to use POST
POST ERROR:
When I try this request: http --form POST http://127.0.0.1:8000/stocks/ ticker='SAM'
I get this error:
AttributeError at /stocks/ Got AttributeError when attempting to get a
value for field ticker on serializer StockSerializer. The
serializer field might be named incorrectly and not match any
attribute or key on the list instance. Original exception text was:
'list' object has no attribute 'ticker'.
You need to remove self.
Remember you are using functions not clases.
#api_view(['GET', 'POST'])
def stock_list(request, format=None):
if request.method == 'GET':
stocks = Stock.objects.all()
serializer = StockSerializer(stocks, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = StockSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Try views.stock_list.as_view() in urls.py
I just want to know how to take two related database entities and send the desired joined data back as a single json response.
For instance, given the following files:
models.py
class Alpha(models.Model):
alpha_id = models.AutoField(primary_key = True)
data = models.CharField(max_length = 255, null = True)
class Beta(models.Model):
beta_id = models.AutoField(primary_key = True)
alpha_fk = models.ForeignKey(Alpha, null = True, on_delete = models.CASCADE)
data = models.CharField(max_length = 255, null = True)
serializers.py
class AlphaSerializer(serializers.ModelSerializer):
class Meta:
model = Alpha
fields = ('alpha_id','data')
class BetaSerializer(serializers.ModelSerializer):
class Meta:
model = Beta
fields = ('beta_id', 'alpha_fk', 'data')
views.py
#csrf_exempt
def AlphaDetailView(request, pk):
try:
modelObject = Alpha.objects.get(pk = pk)
except Alpha.DoesNotExist:
return HttpResponse(status = 404)
if request.method == 'GET':
serializer = AlphaSerializer(modelObject)
return JsonResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = AlphaSerializer(modelObject, data = data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status = 400)
elif request.method == 'PATCH':
data = JSONParser().parse(request)
serializer = AlphaSerializer(modelObject, data = data, partial = True)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status = 400)
elif request.method == 'DELETE':
modelObject.delete()
return HttpResponse(status = 204)
#csrf_exempt
def BetaDetailView(request, pk):
try:
modelObject = Beta.objects.get(pk = pk)
except Beta.DoesNotExist:
return HttpResponse(status = 404)
if request.method == 'GET':
serializer = BetaSerializer(modelObject)
return JsonResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = BetaSerializer(modelObject, data = data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status = 400)
elif request.method == 'PATCH':
data = JSONParser().parse(request)
serializer = BetaSerializer(modelObject, data = data, partial = True)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status = 400)
elif request.method == 'DELETE':
modelObject.delete()
return HttpResponse(status = 204)
urls.py
urlpatterns = [
url(r'^alpha/(?P<pk>[0-9]+)/$', AlphaDetailView),
url(r'^beta/(?P<pk>[0-9]+)/$', BetaDetailView)
]
When I do a GET request on Alpha, I would like to be able to also get all of the fields in Beta which are related by the foreign key, effectively simulating an SQL join.
My coming here is in part a result of the fact that the DRF documentation I've found online seems very vague. Aside from digging through the source code, is there a place where I can go to see detailed information about the available objects and their built-in methods along with expected parameters and return types? All I've found is paragraph descriptions of what different objects do in a very general sense.