I'm trying to use get_serializer_class() and I'm getting error messages. Here's my view -
class CalendarDetail(RetrieveUpdateDestroyAPIView):
def get_serializer_class(self):
if self.request.method == 'GET':
serializer_class = CalendarGETSerializer
elif self.request.method == 'PUT':
serializer_class = CalendarPUTSerializer
return serializer_class
def get(self, request, format=None):
evntname = self.request.GET.get('name')
queryset = Evntmst.objects.filter(evntmst_name=evntname)
serializer = get_serializer_class(queryset)
if queryset:
return Response(serializer.data)
else:
raise Http404
def put(self, request, format=None):
serializer = get_serializer_class(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
And here's my urls.py -
url(r'^deploy/calendartest/$', CalendarDetail.as_view(), name='CalendarDetail'),
As soon as I try to hit the URL I get the following error message -
class CalendarDetail(RetrieveUpdateDestroyAPIView):
^
SyntaxError: invalid syntax
[14/Sep/2014 20:08:16] "GET /deploy/calendartest/?name=cal_daily HTTP/1.1" 500 5
9
I'm guessing it's something internal to the class that I'm calling properly and the syntax error is not necessarily true?
What I don't get is that I've designed the class as I would all my other classes that work, and I have a separate view doing a simple get with one serializer that returns that URL as a 200 NOT a 500.
This had a few issues. One was in the previous view I inadvertently removed a closing bracked on the previous line to the view I posted.
Second, get_serializer_class requires ()(queryset) to call the instance properly.
I'm trying to use get_serializer_class() and I'm getting error messages. Here's my view -
class CalendarDetail(RetrieveUpdateDestroyAPIView):
def get_serializer_class(self):
if self.request.method == 'GET':
serializer_class = CalendarGETSerializer
elif self.request.method == 'PUT':
serializer_class = CalendarPUTSerializer
return serializer_class
def get(self, request, format=None):
evntname = self.request.GET.get('name')
queryset = Evntmst.objects.filter(evntmst_name=evntname)
serializer = get_serializer_class()(queryset)
if queryset:
return Response(serializer.data)
else:
raise Http404
Related
I have a DestroyAPIView in which I am using the perform_delete function to delete an instance. However, I want to send a success message with 200 status. I tried, but in the postman I am getting blank with 204 status. How can I acheive this??
My view:
class UpdateOrderView(UpdateAPIView,DestroyAPIView):
permission_classes = [AllowAny]
#queryset = Order.objects.prefetch_related('order_items').all()
#value = self.kwargs['pk']
queryset = Order.objects.all()
print(queryset)
serializer_class = OrderUpdateSerializer
def perform_destroy(self, instance):
if instance.delete():
return Response({
"message":"Order deleted successfully"
},
status=status.HTTP_200_OK)
else:
pass
The instance is deleted, I have checked the db, but I am not getting success message.
You can override destroy method instead.
class UpdateOrderView(UpdateAPIView,DestroyAPIView):
permission_classes = [AllowAny]
queryset = Order.objects.all()
serializer_class = OrderUpdateSerializer
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response({
"message":"Order deleted successfully"
},
status=status.HTTP_200_OK)
def perform_destroy(self, instance):
instance.delete()
I'm using #action in my ViewSet.
#action(detail=True, methods=('get', 'post', 'put', 'patch'))
def crontab(self, request, pk=None):
template_obj = self.get_object()
app_name = template_obj.application.name
template_name = template_obj.name
periodic_task_name = '%s:%s' % (app_name, template_name)
if request.method == 'GET':
periodic_task = PeriodicTask.objects.filter(
name=periodic_task_name)
if periodic_task.exists():
crontab_obj = periodic_task.get().crontab
serializer = serializers.CrontabScheduleSerializer(crontab_obj)
return Response(serializer.data)
return Response({'crontab': 'crontab does not exist'})
When condition if periodic_task.exists(): is True and return Response(serializer.data) executes I get this error related with TemplateSerializer. This serializer is used in ViewSet, not in my crontab action, and the 'application' field I do not touch in any way.
Any suggestions?
Solution. Put the logic from #action into a separate view with the same URL + '/your_action_name/'.
Also. Can do something like this in your #action, but this is not entirely correct:
if periodic_task.exists():
crontab_obj = periodic_task.get().crontab
serializer = serializers.CrontabScheduleSerializer(crontab_obj)
res_data = {**serializer.data}
return Response(res_data)
Episode has GenericRelation with Like model
class Episode(models.Model):
likes = GenericRelation(Like)
Viewset:
class EpisodeViewSet(viewsets.ModelViewSet, LikedMixin):
serializer_class = EpisodeSerializer
permission_classes = (IsOwnerOrReadOnly,)
def get_queryset(self):
queryset = Episode.objects.filter(story=self.kwargs.get('story_id'))
return queryset
urls:
router.register(r'(?P<story_id>\d+)/episodes', views.EpisodeViewSet, basename='episodes')
LikedMixin has function for performing like action:
#action(detail=True, methods=['POST'])
def like(self, request, pk=None):
obj = self.get_object()
services.add_like(obj, request.user)
return Response()
When I try post request with url 0.0.0.0:3000/stories/1/episodes/1/like/, i recieve error
like() got an unexpected keyword argument 'story_id'.
class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
if isinstance(obj, (Story,)):
return obj.author == request.user
elif isinstance(obj, (Episode,)):
return obj.story.author == request.user
You can try like this..
#action(detail=True, methods=['POST'])
def like(self, request, pk=None, **kwargs):
obj = self.get_object()
services.add_like(obj, request.user)
return Response()
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
Edit
I suspect the whole problem with my UpdateApiView is with the url. No matter how I change it, will return 404.
url(r'verify-phone/(?P<phone_id>^\d+)$', view.VerifyPhone.as_view(), name='verify-phone'),
it returns
{
"detail": "Not found."
}
[18/Apr/2016 01:39:02] "PATCH /api/verify-phone/phone_id=00980 HTTP/1.1" 404 4941
Why?
views.py
class VerifyPhone(generics.UpdateAPIView):
permission_classes = (AllowAny,)
serializer_class = serializers.VerifyPhoneSerializer
allowed_methods = ['PATCH']
lookup_field = 'phone_id'
def get_queryset(self):
phone_id = self.request.query_params.get('phone_id', None)
queryset = User.objects.filter(phone_id=phone_id)
return queryset
def update(self, request, *args, **kwargs):
print('inside update')
print(request.data)
partial = kwargs.pop('partial', False)
instance = self.get_object()
print(instance)
serializer = self.get_serializer(instance, data=request.data, partial=partial)
print(serializer)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
print('done perform update')
return Response(serializer.data)
serializers.py
class VerifyPhoneSerializer(serializers.ModelSerializer):
regex = r'\d+'
verification_code = serializers.RegexField(regex, max_length=7, min_length=7, allow_blank=False)
phone_id = serializers.HyperlinkedRelatedField(view_name='verify-phone', lookup_field='phone_id', read_only=True)
class Meta:
model = User
fields = ('verification_code', 'phone_id')
def validate(self, data):
verification = api.tokens.verify(data['phone_id'], data['verification_code'])
if verification.response.status_code != 200:
raise serializers.ValidationError("Invalid verification code.")
return data
def update(self, instance, validated_data):
instance.phone_number_validated = True
instance.save()
return instance
Second question Is this correct to get phone_id from the views?
phone_id = serializers.HyperlinkedRelatedField(view_name='verify-phone', lookup_field='phone_id', read_only=True)
Looking at your api url def, I think you should call:
/api/verify-phone/00980
instead of
/api/verify-phone/phone_id=00980
I also think something is wrong with the url def itself (the ^ before \d):
url(r'verify-phone/(?P<phone_id>^\d+)$', view.VerifyPhone.as_view(), name='verify-phone')
should be
url(r'verify-phone/(?P<phone_id>\d+)$', view.VerifyPhone.as_view(), name='verify-phone')
or
url(r'verify-phone/(?P<phone_id>\d{5})$', view.VerifyPhone.as_view(), name='verify-phone')