The post method does not bring a form to enter the field details. I am able to enter data using json format. I followed the Django documentation to create the API
This is my serializer code:
from rest_framework import serializers
from .models import Tasks
# converting objects into datatypes understandable by javaScript and frontend frameworks
class TasksSerializers(serializers.ModelSerializer):
class Meta:
model = Tasks
fields = "__all__"
views.py
#api_view(['GET', 'POST'])
def task_list(request, format=None):
serializer_class = TasksSerializers
if request.method == 'GET':
tasks = Tasks.objects.all()
serializer = TasksSerializers(tasks, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = TasksSerializers(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)
print(request.method)
return Response(serializer.data, status=status.HTTP_201_CREATED)
models.py
class Tasks(models.Model):
task_id = models.AutoField(db_column="task_id", primary_key=True, unique="true")
task_description = models.TextField(db_column="task_description", null=True)
task_status= models.CharField(max_length=399, db_column="task_status", default="Not started" )
task_priority = models.CharField(max_length=399, db_column="task_priority", default="Low priority")
asignee_name = models.TextField(db_column="asignee_name", blank=False, null=False)
deadline = models.DateField(db_column="deadline", blank=False, null=False)
emp = models.ForeignKey(Employee,on_delete=models.CASCADE,default='')
# metadata for the table
class Meta:
db_table = "Tasks"
What have I done wrong?
Related
MY model
class XP(models.Model):
bizuser = models.ForeignKey(BizUser, on_delete=models.CASCADE)
current_xp_price = models.IntegerField(default=0)
xp_created_at = models.DateTimeField(auto_now_add=True)
xp_updated_at = models.DateTimeField(auto_now_add=True)
i have this function that creates an XP i want if the current user is authenticated(jwttokens) the user can then go ahead to create the XP .when i go to post this data i get to fields that i have to fill that is current_xp_price and bizuser which is a ForeignKey
Views
class create_xp(APIView):
def post(self, request):
if request.user.is_authenticated:
current_user = request.BizUser
serializer = XPSerializer(data=request.data)
request.data["bizuser"] = current_user.id
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)
else:
return Response(status=status.HTTP_401_UNAUTHORIZED)
serializers
class XPSerializer(serializers.ModelSerializer):
class Meta:
model = XP
fields = ['current_xp_price', ]
Hello I am working on a project in which I'm making serializers
and I send post requests using postman. This is working fine but this is a very small part of the application and the code will grow to be very large. If there is a better way of doing this in which I write smaller code then I would like to employ that.
Right now the way I'm saving the information is as follows
models.py
class Services(models.Model):
business = models.ForeignKey(Business, on_delete=models.CASCADE)
service = models.CharField(max_length=30, blank=True)
serializers.py
class ServiceSerializer(serializers.ModelSerializer):
class Meta:
model = Services
fields = ('id', 'business', 'service')
views.py
class ServiceAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
data = request.data
business = Business.objects.get(user=request.user)
data['business'] = business.pk
serializer = BusinessSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py
urlpatterns = [
path('service/', ServiceAPIView.as_view()),
]
Edited*
Here is the business model
class Business(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
business_name = models.CharField(max_length=50, blank=True)
invoices_terms = models.TextField(max_length=100, blank=True)
desc = models.TextField(max_length=1000, blank=True)
website = models.URLField(max_length=200, blank=True)
tax_percentage = models.DecimalField(blank=True, max_digits=5, decimal_places=3)
labour_rate_per_hour = models.DecimalField(blank=True, max_digits=5, decimal_places=2)
tax_hst_number = models.IntegerField(blank=True)
Well the code looks ok and it's also ok to have deep modules.
A little update could be the following:
class ServiceAPIView(APIView):
permission_classes = [IsAuthenticated,]
serializer_class = ServiceSerializer
def post(self, request):
data = request.data
business = Business.objects.get(user=request.user)
data['business'] = business.pk
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
In this way you can write only one Response line for each view request method and avoid to use if/else statements
I am creating sample rest API using django-rest-framework,
I refereed the tutorial on there website https://www.django-rest-framework.org/tutorial/1-serialization/
I api is working fine when list and create new object but it throwing the exception during detail view(http://127.0.0.1:8000/cars/1) of object.
I have added my code snippet below, Please let me know what wrong i am doing
Models.py
class Car(models.Model):
created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=100, blank=True, default='')
price = models.TextField()
class Meta:
ordering = ('created',)
serializers.py
class CarsSerializer(serializers.ModelSerializer):
class Meta:
model = Car
id = serializers.IntegerField(read_only=True)
fields = ('id', 'created', 'name', 'price')
Views.py
#csrf_exempt
def car_list(request):
"""
List all code cars, or create a new car.
"""
if request.method == 'GET':
cars = Car.objects.all()
serializer = CarsSerializer(cars, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
data = JSONParser().parse(request)
serializer = CarsSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
#csrf_exempt
def car_detail(request, pk):
"""
Retrieve, update or delete a code cars.
"""
try:
car = Car.objects.get(pk=pk)
except Car.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = CarsSerializer(Car)
return JsonResponse(serializer.data)
elif request.method == 'PUT':
data = JSONParser().parse(request)
serializer = CarsSerializer(Car, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
Car.delete()
return HttpResponse(status=204)
Urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
path('cars/', views.car_list),
path('cars/<int:pk>/', views.car_detail),
]
First of all you need to post exception.
But the problem is that you pass class and not instance of class to your serializer.
try:
car = Car.objects.get(pk=pk)
except Car.DoesNotExist:
return HttpResponse(status=404)
if request.method == 'GET':
serializer = CarsSerializer(car) # <-- car not Car (this type of error should be fixed everywhere)
return JsonResponse(serializer.data)
And in Car.delete() should be car.delete()
I have UserProfile model that contains phone, profile_photo and some fields of Django default User model like first_name, last_name, email and I am trying to update some of these fields.
models.py
class UserProfile(models.Model):
user = models.ForeignKey(User, verbose_name="User")
phone = models.CharField(max_length=16, verbose_name="Phone")
profile_photo = models.ImageField(null=True, blank=True, upload_to=user_directory_path, verbose_name="Profile Photo")
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('url', 'first_name', 'last_name', 'email')
class UserProfileSerializer(serializers.ModelSerializer):
user = UserSerializer(partial=True)
class Meta:
model = UserProfile
fields = '__all__'
def create(self, validated_data):
user_profile = UserProfile.objects.create(**validated_data)
return user_profile
views.py
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
authentication_classes = (TokenAuthentication,)
#detail_route(methods=['PATCH'], url_path='update-partial')
def user_profile_update_partial(self, request, pk=None):
profile = UserProfile.objects.get(id=pk)
serializer = self.get_serializer(profile, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
If I send profile_photo, phone, first_name or last_name data with this #detail_route I am only able to update phone and profile_photo fields. Also getting Bad Request error when profile_photo data not sending.
How can I implement the partial_update with PATCH method?
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all()
serializer_class = UserProfileSerializer
authentication_classes = (TokenAuthentication,)
def partial_update(self, request, *args, **kwargs):
profile = self.get_object()
serializer = self.get_serializer(profile, data=request.data, partial=True)
if serializer.is_valid():
user_serializer = UserSerializer(profile.user, data=request.data, partial=True)
if user_serializer.is_valid():
user_serializer.save()
serializer.save()
return Response(serializer.data, status=status.HTTP_202_ACCEPTED)
else:
return Response(data=user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response(data=serializer.errors,status=status.HTTP_400_BAD_REQUEST)
Q1:How to implement PATCH method?
A1:Override partial_update method.
Q2:How to update first_name or last_name?
A2:Update it with another Serializer named UserSerializer.(If you want update password,you need use make_password method to create encoded password before save raw password to database)
I'm building a REST web service, the GET method seems to be working all right
but when it comes to POST error message always shows up:
'dict' object has no attribute 'save'
models.py
from django.db import models
class Users(models.Model):
Fullname = models.CharField(max_length=50)
Username = models.CharField(max_length=15)
Password = models.CharField(max_length=8)
Email = models.CharField(max_length=50, unique=True)
Type = models.CharField(max_length=5)
TwitterName = models.CharField(max_length=15, unique=True)
FacebookName = models.CharField(max_length=15, unique=True)
CreationDate = models.DateTimeField()
serializer.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = Users
fields = ('Fullname', 'Username', 'Email', 'Password', 'Type', 'TwitterName', 'FacebookName')
views.py
#api_view(['GET', 'POST'])
def users_list(request, format=None):
if request.method == 'GET':
users = Users.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = UserSerializer(request.DATA, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)
I'm using PyCharm and Django 1.7
If you want to save the POST data then you should pass the data to data keyword argument:
serializer = UserSerializer(data=request.DATA, many=True)
if serializer.is_valid():
...
Also I would suggest you to use Class based views with Mixins as that will make your code much cleaner and shorter:
from rest_framework import generics, mixins
class UserList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Users.objects.all()
serializer_class = UserSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)