How to serialize multiple query set to json Response in django rest frame work - django-rest-framework

I am getting a list of committees by user using a get method in which I am sending a user id but I am getting an error Committee object is not serialize I have serializer created but I dont't know how to serializer the queryset of that particular user id result.
below is my views.py file
def get(self, request, user_id):
get_committees = Committee.objects.filter(user=Profile.objects.get(id=user_id))
data = {
"status": "success",
"data":get_committees
}
res = Response(serializer.data, status=status.HTTP_200_OK)
below is my serializer.py
class MyCommitteesSerializer(serializers.ModelSerializer):
def get_queryset(self, user_id):
my_committees =
Committee.objects.filter(user=Profile.objects.get(id=user_id))
return my_committees

from your code in get method
"data":get_committees
this get_committees is a list and you are trying to return a list but you can only return json, and so you are getting the message.
You can do this in a better way
define your serializer as -
class MyCommitteesSerializer(serializers.ModelSerializer):
class Meta:
model = Committee
fields = ""_all__"
and define your views as -
class MyCommitteesView(generics.ListAPIView):
serializer_class = MyCommitteesSerializer
def get_queryset(self):
queryset = Committee.objects.filter(user=Profile.objects.get(id=self.request.user_id))
return queryset
the serializer will take care of serialization and you can customize this according to your needs.
or else you will have to manually convert your get_committes into json format before returning.

Related

I have to create serializer instance without data since i am not accepting any data from user

Here i am trying to create serializer instance without data argument because all i want to create a "Like" object which requires "user" object which i can get from request and "post" object that i am getting through querying Post model with pk but since i am not passing any data argument while deserializing it will throw an error.
So how can create instance without passing data argument or do i have to change my code and add data argument?
class Like(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="likes")
liked_by = models.ForeignKey(User, on_delete=models.RESTRICT, related_name = "liked_posts")
def __str__(self):
return "{0} liked by {1}".format(self.post.img, self.liked_by.username)
class LikeSerializer(serializers.ModelSerializer):
liked_by = UserSerializer(read_only=True)
class Meta:
model = Like
fields = ("id","post", "liked_by")
class AddLike(APIView):
permission_classes = [IsAuthenticated]
def post(self, request, pk):
post = Post.objects.get(pk=pk)
user = request.user
serializer = LikeSerializer()
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializer.save(post=post, liked_by=user)
return Response(data= serializer.data, status=status.HTTP_201_CREATED)
I think you can set the post field as read_only in the LikeSerializer.
class LikeSerializer(serializers.ModelSerializer):
liked_by = UserSerializer(read_only=True)
class Meta:
model = Like
fields = ("id","post", "liked_by")
extra_kwargs = {
'post': { 'read_only': True }
}

'QuerySet' object has no attribute 'pk'

#models
class Student(models.Model):
firstname = models.CharField(max_length=100,default='ll')
lastname = models.CharField(max_length=100,default='fewf')
id_code = models.CharField(max_length=10,default=0,unique=True)
melli = models.CharField(max_length=30,default=0,unique=True)
personal_pic = models.ImageField(upload_to=studentFile)
major = models.ForeignKey(Major, on_delete=models.PROTECT,default=0)
date_of_start = models.DateField(default=datetime.date.today)
def __str__(self):
return self.id_code
#views
class loginView(APIView):
def post(self, request):
data = request.data
melli = data.get('melli')
id_code = data.get('id_code')
student = Student.objects.filter(id_code=id_code,melli=melli)
if not student.exists():
return Response('error')
serializer = StudentSerializer(student,data=data)
serializer.is_valid()
return Response(serializer.data)
when i try to submit a post request i was excepted to recive a response but i got an error. how can i solve it?
You serialize a collection of elements, so you should work with many=True:
serializer = StudentSerializer(student,data=data, many=True)
in case you want to only work with a single object, you need to retrieve a single object, not a collection of objects, for example with .get(…) [Django-doc] instead of .filter(…) [Django-doc].
Model.filter returns a queryset, which is like a list of models, rather than a specific model. Instead, you should use get, which returns a single model instance:
student = Student.objects.get(id_code=id_code,melli=melli)
If you intend on there being more than 1 student in this specific query, you can add many=True to your serializer instead:
serializer = StudentSerializer(student,data=data, many=True)

DRF: How to get Users object in a get method as a Response?

How can I get all user objects in get method in views.py with other models?
views.py
class WebDashboardViews(generics.ListAPIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAdminUser,permissions.IsAuthenticated,)
serializer_class = serializers.DashboardSerializer
def get(self, request, format=None):
all_user_queryset = models.User.objects.all()
if not all_user_queryset:
total_user = 0
else:
total_user = all_user_queryset.count()
total_android_user = models.UserMobileDevice.objects.filter(os="Android")
if not total_android_user:
total_android_count = 0
else:
total_android_count = total_android_user.count()
content = {'total_user':total_user,'total_android_count':total_android_count, all_users: all_user_queryset}
return Response(content)
I want the user object in all_users key. But I am getting an error:
Object of type User is not JSON serializable
My serializer code is :
class DashboardSerializer(serializers.ModelSerializer):
class Meta:
model = models.User
field = ['id','created_at','name']
I am not sure what I am doing here. Any help will be highly appreciated. Thanks
You get that error because you are trying to respond with not-serialized objects here: all_users: all_user_queryset
You need to serialize them first (I guess you have an UserSerializer, if don't, just rename your DashboardSerializer to UserSerializer because it is just what it is):
user_serializer = UserSerializer(all_user_queryset, many=True)
content = {'total_user':total_user,'total_android_count':total_android_count, all_users: user_serializer.data}
return Response(content)

Cannot generate post request for multiple data

I am trying to take input multiple data object in post request, but getting such error.
non_field_errors: [ Invalid data. Expected a dictionary, but got a list. ]
models.py
class OrderProduct(BaseModel):
product = models.ForeignKey(Product,on_delete=models.CASCADE)
order = models.ForeignKey(Order,on_delete=models.CASCADE)
order_product_price = models.FloatField(blank=False,null=False,default=0) # product may belong to offer do the price
order_product_qty = models.FloatField(default=1)
serializers.py
class OrderProductSerializer(serializers.ModelSerializer):
def update(self,instance,validated_data):
product = self.validated_data.pop('product')
order = self.validated_data.pop('order')
instance.orderproduct_qty =
self.validated_data.get('orderproduct_qty',instance.orderproduct_qty)
instance.product = product
instance.order = order
instance.save()
return instance
class Meta:
model = OrderProduct
fields = '__all__'
views.py
def post(self,request,*args,**kwargs):
if request.data['contact_number'] == '':
request.POST._mutable =True
request.data['contact_number'] = request.user.mobile_number
request.POST._mutable = False
serializer = OrderSerializer(data=request.data,many=isinstance(request.data,list),context={'request': request})
print(serializer)
if serializer.is_valid():
serializer.save(user = request.user,created_by = request.user)
return Response(serializer.data,status=status.HTTP_200_OK)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
urls.py
path('orderproduct/',views.OrderProductList.as_view()),
When you call serializer.save(). It's only perform create() action which is only create one and accept dictionary data type only. If you want to save multiple data like that, you will have to override the create function of the serializer class. You can do something similar like this or run a for loop.
serializers.py
def create(self, validate_data):
# Get the data objects you need to perform bulk create
order_products = OrderProduct.objects.bulk_create(validate_data)
return order_products
views.py
if serializer.is_valid(raise_exception=True):
# Replace the serializer.save() by this line to trigger the create method in serializer
self.perform_create(serializer)
return Response(...)

creating two models in one serializer of django rest framework

During registration of a user I would like to have both a User object and a EmailContact object created in one api call. The two objects should not be linked.
I have the following serializer:
class RegistrationSerializer(serializers.Serializer):
userserializer=UserAccountSerializer() #reuse existing modelserializer
emailcontactserializer=EmailContactSerializer() #reuse existing modelserializer
def create(self, validated_data):
emailcontact_data = validated_data.pop('emailcontactserializer')
user_data = validated_data.pop('userserializer')
emailcontact= EmailContact.objects.create(**emailcontact_data)
user= User.objects.create(**user_data)
return user
and the following Apiview:
class RegistrationAPIView(APIView):
permission_classes = (AllowAny,)
serializer_class = RegistrationSerializer
def post(self, request):
serializer = self.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)
The error I get is the following (occurs after the serializer.save()):
AttributeError at /api/register
Got AttributeError when attempting to get a value for field userserializer on serializer RegistrationSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the User instance.
Original exception text was: 'User' object has no attribute 'userserializer'.
In your RegistrationSerializer.create() method, you're returning a User object. The serializer will try to serialize that object into this representation:
{
'userserializer': x,
'emailcontactserializer': y
}
But it's complaining because the User you returned doesn't have a userserializer field.
If you really want to return a User from this API call, you could make your RegistrationSerializer a ModelSerializer with Meta.model=User, and override perform_create to pop out the emailcontact_data. (I'd name the field something like RegistrationSerializer.email_contact to make the representation clearer, IMO the phrase "serializer" shouldn't be present on the client-visible portion of the API).
Alternatively, if you want to render both of your sub-serializers, you can create a RegistrationSerializer instance in RegistrationSerializer.create by passing in the data, something like
return RegistrationSerializer(data={'emailcontactserializer':
emailcontact_data, 'userserializer': user_data})

Resources