Unable to get repr for queryset when call from Viewset - django

I am trying to call a queryset for a model to add to my serializer using objects.all() but the debug said Unable to set repr for <class 'django.db.models.query.Queryset'>
Here is my viewset
class TransactionReceiptViewSet(viewsets.GenericViewSet,
viewsets.mixins.RetrieveModelMixin,
viewsets.mixins.ListModelMixin):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
serializer_class = base_serializers.TransactionReceiptSerializer
queryset = models.TransactionReceipt.objects.all()
def get_queryset(self):
user = self.request.user
return models.TransactionReceipt.objects.filter(user_profile=user)
def retrieve(self, request, *args, **kwargs):
response = super(TransactionReceiptViewSet, self).retrieve(request, *args, **kwargs)
receipt = self.get_object()
serializer = self.get_serializer(receipt)
product_qs = models.ProductReceipt.objects.all()
products_data = base_serializers.ProductReceiptSerializer(
product_qs, many=True)
serializer.data['products'] = products_data
return Response(serializer.data)
and here is the model I tried to call for
class ProductReceipt(models.Model):
id = models.AutoField(primary_key=True)
amount = models.IntegerField(default=1)
product = models.ForeignKey(Product, on_delete=models.DO_NOTHING, default=None)
created_date = models.DateTimeField('Date of purchase', auto_now=True)
transaction_receipt = models.ForeignKey(TransactionReceipt, on_delete=models.CASCADE)
price = models.IntegerField(default=0)
def __str__(self):
return "object created"
def __init__(self):
super().__init__()
self.product = Product()
self.transaction_receipt = TransactionReceipt()
def save(self, **kwargs):
self.amount = 1
self.created_date = datetime.now()
self.price = self.product.price_tag.price
When I debug the API, it said that Unable to set repr for <class 'django.db.models.query.Queryset'> in product_qs and nothing is returned
Edit:
I think that the Model have to do something with this. I have tried to create a ModelViewSet for ProductReceipt and it worked fine. But when i try to make the query manually. it somehow broke the mapping to the foreign key??? and return nothing?

Okey lets check a couple of things. First of all in your ProductReceipt class the def save(self, **kwargs) method is not calling super and that's a huge problem because the objects are not gonna be saved ever. Secondly, in the ProductReceipt class the def __init__(self) method you are assigning a new Product and a new TransactionReceipt to your ProductReceipt instance, but you are not setting the data of this two objects neither saving them in any place (maybe you should assign them inside save method and save them before calling super?).
Try this corrections and if it keeps not working we will another possible errors.
Finally, def __str__(self) is a string representation of your object, it will be a good implementation for example:
def __str__(self):
return self.product.name + ' x' + str(amount)

Turn out that the product field is not set to null=True. And i have old data with that field point to nothing. There for it break when trying to query from the database. In short, i didn't migrate properly.

Related

How to patch several objects at the same time in Django Rest Framework?

I'm creating an app in which notifications model exists. That is why I need a behavior like this: when a person requests the notification page, the field is_read which is boolean turns from default FALSE to TRUE. The trouble is that there could be many of objects, so how to set to TRUE all of them?
Model:
class Notification(models.Model):
is_read = models.BooleanField(default=False)
notification_from = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="notiffrom")
notification_to = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="notifto")
View:
class UserNotificationView(ListModelMixin, GenericAPIView, CreateModelMixin):
serializer_class = NotificationSerializer
def get_queryset(self):
notification_to = self.kwargs["notification_to"]
return Notification.objects.filter(notification_to=notification_to)
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
I know that there are bulk requests in Django but struggle with making them with DRF. Maybe there are some other ways?
You could add the update function in the get_queryset function.
class UserNotificationView(ListModelMixin, GenericAPIView, CreateModelMixin):
serializer_class = NotificationSerializer
def get_queryset(self):
notification_to = self.kwargs["notification_to"]
queryset = Notification.objects.filter(notification_to=notification_to)
queryset.update(is_read = True)
return queryset
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)

In django-rest-framework, I want to output the childdb in the same parentdb by putting the parentdb name in the url parameter

There is a model that binds the user with a foreignkey. What I want to do is set the url parameter to
I'm writing an api that prints the items of children with the same parent when I put as_view/int:parentpk, but I can't implement it due to my lack of skills. Please help
Here is a model.py that accepts a user as a foreignkey
class TestingTasks(models.Model):
Taskname = models.CharField(max_length=100, unique=True)
dateofuse = models.DateTimeField(auto_now_add=True)
Compressing = models.TextField()
Path = models.FileField(null=True)
parent_id = models.ForeignKey(User,related_name='users', on_delete=models.CASCADE,default=1)
And here is views.py
class TestingAPI(APIView):
permission_classes = [AllowAny]
def get(self, request, company_id):
instance = TestingTasks.objects.filter(parent_id=id)
serializer_class = TestingSerializer(instance)
return Response(serializer_class.data)
Here is urls.py
path("Testing/<int:company_id>",views.TestingAPI.as_view())
I need to implement a total of three get, put, and delete, but I can't do the rest because I can't get.
I'd appreciate it if you could give me a direction on how to do it. Have a nice day.
just add the functions in class
class TestingAPI(APIView):
permission_classes = [AllowAny]
def get(self, request, company_id):
instance = TestingTasks.objects.filter(parent_id=company_id)
serializer_class = TestingSerializer(instance)
return Response(serializer_class.data)
def put(self, request, company_id):
...
def delete(self, request, company_id):
...

REST Django - How to Modify a Serialized File Before it is Put Into Model

I am hoping that I can find a way to resize an uploaded image file before it is put into the database.
I am new to Django with REST, so I am not sure how this would be done. It seems that whatever is serialized is just kind of automatically railroaded right into the model. Which I suppose is the point (it's certainly an easy thing to setup).
To clarify, I already have a function tested and working that resizes the image for me. That can be modified as needed and is no problem for me. The issue really is about sort of "intercepting" the image, making my changes, and then putting it into the model. Could someone help me out with some ideas of tactics to get that done? Thanks.
The Model:
class Media(models.Model):
objects = None
username = models.ForeignKey(User, to_field='username',
related_name="Upload_username",
on_delete=models.DO_NOTHING)
date = models.DateTimeField(auto_now_add=True)
media = models.FileField(upload_to='albumMedia', null=True)
file_type = models.CharField(max_length=12)
MEDIA_TYPES = (
('I', "Image"),
('V', "Video")
)
media_type = models.CharField(max_length=1, choices=MEDIA_TYPES, default='I')
user_access = models.CharField(max_length=1, choices=ACCESSIBILITY, default='P')
class Meta:
verbose_name = "MediaManager"
The View with post method:
class MediaView(APIView):
queryset = Media.objects.all()
parser_classes = (MultiPartParser, FormParser)
permission_classes = [permissions.IsAuthenticated, ]
serializer_class = MediaSerializer
def post(self, request, *args, **kwargs):
user = self.request.user
print(user.username)
request.data.update({"username": user.username})
media_serializer = MediaSerializer(data=request.data)
# media_serializer.update('username', user.username)
if media_serializer .is_valid():
media_serializer.save()
return Response(media_serializer.data, status=status.HTTP_201_CREATED)
else:
print('error', media_serializer.errors)
return Response(media_serializer.errors,status=status.HTTP_400_BAD_REQUEST)
The Serializer:
class MediaSerializer(serializers.ModelSerializer):
class Meta:
model = Media
fields = '__all__'
def to_representation(self, instance):
data = super(MediaSerializer, self).to_representation(instance)
return data
You can use validate method to validate and/or change the values from data dictionary.
class MediaSerializer(serializers.ModelSerializer):
...
def validate(self, data):
value_from_form = data['value_from_form']
value_from_form = 'Something else'
data['value_from_form'] = value_from_form
return data

Django Rest Framework: validate HiddenField CurrentUserDefault property

I am using DRF to create an API in a single page application.
I have a customer user class to which I have only added a is_manager flag and a managerEntity model where users that have the is_manager flag as True can create managerEntities becoming owners of them.
The problem is that I can't seem to figure out how to validate the data from the serializer before create method to check whether the is_manager is set or not. If set, the managerEntity should be created, if not, raise an exception.
class DeepmetricsUser(AbstractUser):
is_manager = models.BooleanField(default=False)
class managerEntity(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
team = models.ManyToManyField(get_user_model(), blank=True)
views.py
class managersEntityViewSet(viewsets.ModelViewSet):
queryset = managerEntity.objects.all()
serializer_class = managerEntityModelSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
return self.queryset.filter(Q(owner = self.request.user) | Q(team=self.request.user.id))
def create(self, request, *args, **kwargs):
serializer = managerEntitySerializer(data=request.data, context={"request": self.request})
serializer.is_valid(raise_exception=True)
res = serializer.save()
data = managerEntityModelSerializer(res).data
return Response(data, status=status.HTTP_201_CREATED)
serializer.py
class managerEntitySerializer(serializers.Serializer):
name = serializers.CharField(max_length=255)
owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
def create(self, data):
res = managerEntity.objects.create(**data)
return res
You need to override the validate method in Serializer
def validate(self, attrs):
if not self.context["request"].user.is_manager:
raise serializers.ValidationError("Validation error")
return attrs
I found a solution that fits better my needs by using permissions. The answer provided by Shakeel is correct as I asked for validation and that should be done as he suggested but, what I really wanted to do was checking for enough clearance for the user to manipulate a resource, then, permissions is what's best fits:
class createManagerEntity(BasePermission):
message = "Not enough privilegies"
def has_permission(self, request, view):
return request.user.is_manager

view count increase in DRF

I need to increase the view count with 1 on each refresh. I'm not sure about the method since I'm new to DRF. Thanks in advance.
models.py
class Module(models.Model):
name = models.CharField(max_length=250, default="")
view_count = models.IntegerField(default=0)
serializers.py
class ModuleSerializer(serializers.ModelSerializer):
class Meta:
model = Module
fields = "__all__"
views.py
class ModuleView(generics.ListAPIView):
queryset = Module.objects.all()
serializer_class = ModuleSerializer
def get(self, request):
obj = self.get_object
print(obj)
obj.view_count = obj.view_count + 1
obj.save(view_count="view_count")
return super().get(request)
i implemented view count with F expression because a view count is basicly a race condidition and the docs clearly state that
Avoiding race conditions using F()
Documentation
class ElonDetail(generics.RetrieveAPIView):
queryset = Elon.objects.all()
serializer_class = ElonDetailSerializer
lookup_field = 'slug'
#retrieve
def retrieve(self, request, *args, **kwargs):
obj = self.get_object()
print(obj)
obj.view = obj.view + 1
obj.save(update_fields=['view',])
serializer = self.get_serializer(obj)
return Response(serializer.data, status=200)
here i used RetrieveAPIView