How to implement this function?

Viewed 19

I have model Contact

class Contact(models.Model):

    name = models.CharField(max_length=255)
    phone = models.CharField(max_length=255)
    appearance = models.PositiveIntegerField(default=0)

    def get_appear(self):
        self.appearance += 1

where appearance is how match I'm browsing this endpoint

my views.py is :

class ContactView(generics.RetrieveAPIView):
    queryset = Contact.objects.all()
    serializer_class = ContactIdSerializer


    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.get_appear()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

serializers.py:

class ContactIdSerializer(serializers.ModelSerializer):

    class Meta:
        model = Contact

        fields = ['id', 'name', 'phone', 'address', 'appearance']

Problem is when I go to my id :

http://127.0.0.1:8000/api/v1/contacts/3/

every time appearance should increase by 1 , but this value always equals 1

and value of appearance in db always equals 0

2 Answers

You should save the item:

class Contact(models.Model):
    # …

    def get_appear(self, save=True):
        self.appearance += 1
        if save:
            self.save(update_fields=('appearance',))

or if there might be race conditions:

from django.db.models import F

class Contact(models.Model):
    # …

    def get_appear(self, save=True):
        old = self.appearance
        if save:
            self.appearance = F('appearance') + 1
            self.save(update_fields=('appearance',))
        self.appearance = old + 1

This will make a query that looks like:

UPDATE contact
SET appearance = appearance + 1
WHERE pk = pk

so if multiple queries run almost simultaneously, it will each time increment the appearance column.

Resolving by adding instance.save()

Related