Home > Enterprise >  Django REST - hide deserialized data
Django REST - hide deserialized data

Time:11-25

I would like to store some data in one of my database field. The data is added to that field while deserialization with POST method. Later when I want to show data with GET method I don't want that one field to be presented.

When I do POST I deserialize that string:

{
    "car_id": 3,
    "rating": 3
}

Later in views.py I do the deserialization while POST:

@api_view(['POST'])
def car_rate(request):

    if request.method == 'POST':
        rate_data = JSONParser().parse(request)
        rate_serializer = CarRateSerializer(data=rate_data)

        if rate_serializer.is_valid():
            try:
                car_obj = Car.objects.get(pk=rate_data['car_id'])
            except Car.DoesNotExist:
                return JsonResponse({'message': 'The car with given ID does not exist!'}, status=status.HTTP_404_NOT_FOUND)
        
            # check if rate is from 1 to 5
            r = rate_serializer.validated_data['rating']
            if int(r) >= 1 and int(r) <= 5:
                rate_serializer.save()
                return JsonResponse({'message':'The rate is in the scope!'})
            else:
                return JsonResponse({'message':'The rate is NOT in the scope!'})
        
        return JsonResponse(rate_serializer.errors)

And there is my models.py:

class Car(models.Model):
    make = models.CharField(max_length=15)
    model = models.CharField(max_length=15)
    avg_rating = models.FloatField(default=0)

    def __str__(self):      # print it when Car instance is needed
        return self.make


class CarRate(models.Model):
    car_id = models.ForeignKey(Car, related_name='rates',
                            on_delete=models.CASCADE,
                            default=0)
    rating = models.PositiveIntegerField(default=0)

The code does works (somehow). For now there can be added rates for one car (multiple rates) with POST moethods. I store the rates in CarRate class and later it will be used to calculate the average rate for a car. I just simply don't want to print it out with GET.

This is my output right now:

{
    "id": 2,
    "make": "Volkswagen",
    "model": "Golf",
    "rates": [
        4,
        4,
        2,
        3
    ],
    "avg_rating": 0.0
},

I simply want the rates field to be invisible while printing.

I read about defer() method and tried it out, but nothing happened. Any help?

CodePudding user response:

If you absolutely don't want that field to be in your database ever, then you can simply remove that field from the Serializer field option (You named that CarRateSerializer) But if you want that to be in your database but you don't want that to show as output, you can use extra_kwargs with 'write_only': True in your serializer class. I'm giving you an example I used for one of my projects

class TopicSerializer(serializers.ModelSerializer):

class Meta:
    model = Topic
    fields = ['id','title', 'totalMarks', 'status', 'categoryID']
    extra_kwargs = {'categoryID': {'write_only': True}}

for your code, you can add this line of code below fields in that class Meta of your CarRateSerializer

extra_kwargs = {'rating': {'write_only': True}}

I hope this should solve your issue

CodePudding user response:

Just remove rating field from, CarRateSerializer OR you can create a new Serializer for CarRate.

  • Related