Search code examples
django-modelsdjango-rest-frameworkdjango-viewsdjango-serializerpgadmin-4

Update Successfully but Data not update in db. Django rest framework


I'm working on my final year project, and I need some help to understand what is actually happening, The problem is that: I hit the Update request through postman which gives the successful message for updating the data. but when I check my Database there is no updated data. I also did the debugging but there was no exception by which I can understand the problem Anyone can please help me? I'm using

PgAdmin for my database.

Django==4.0.2

djangorestframework==3.13.1

djangorestframework-jwt==1.11.0

djangorestframework-simplejwt==5.0.0

psycopg2==2.9.3**.

My Models:

class Company(Base):
    company_name = models.CharField(max_length=255, db_column='Company_Name')
    company_email = models.EmailField(unique=True, max_length=255, db_column='company_email')
    company_manager_name = models.CharField(max_length=255, db_column='Manager_Name')
    company_address = models.CharField(max_length=255, db_column='Company_address')
    about_company = models.TextField()
    company_website = models.URLField(max_length=200)
    is_active = models.BooleanField(default=True, db_column='IsActive', help_text='I will use this for enable/disable '
                                                                                  'a specific record')

    class Meta:
        db_table: 'Company'

    def __str__(self):
        return self.company_name

    def save(self, *args, **kwargs):
        try:
            if not self.pk:
                self.company_email = self.company_email.replace(" ", "").lower()
                super().save()
        except Exception:
            raise
class Base(models.Model):
    """Following fields are abstract and will be use in All over the project Any time Anywhere"""
    create_by = models.BigIntegerField(db_column='CreatedBy', null=True, blank=True, default=0)
    create_on = models.DateTimeField(db_column='CreatedOn', auto_now_add=True)
    modified_by = models.BigIntegerField(db_column='ModifiedBy', null=True, blank=True, default=0)
    modified_on = models.DateTimeField(db_column='ModifiedOn', auto_now=True)
    deleted_by = models.BigIntegerField(db_column='DeletedBy', null=True, blank=True, default=0)
    deleted_on = models.DateTimeField(db_column='DeletedOn', auto_now=True)
    status = models.BigIntegerField(db_column='Status', default=0, help_text='I will use this field for making'
                                                                             'the status like pending approved and '
                                                                             'for some other purpose by Default it is '
                                                                             'Zero which has no meaning', )

    class Meta:
        abstract: True

serializer.py:

class CompanyUpdateSerializer(serializers.ModelSerializer):
    company_name = serializers.CharField(required=True, allow_null=False, allow_blank=False)
    company_email = serializers.CharField(required=True, allow_null=False, allow_blank=False)
    company_manager_name = serializers.CharField(required=True, allow_null=False, allow_blank=False)
    company_address = serializers.CharField(required=True, allow_null=False, allow_blank=False)
    about_company = serializers.CharField(required=True, allow_null=False, allow_blank=False)
    company_website = serializers.URLField(allow_blank=False, allow_null=False)

    class Meta:
        model = Company
        fields = ['id', 'company_name', 'company_email', 'company_manager_name', 'company_address', 'about_company',
                  'company_website']

    def update(self, instance, validated_data):
        try:
            instance.company_name = validated_data.get('company_name', instance.company_name)
            instance.company_email = validated_data.get('company_email', instance.company_email)
            instance.company_manager_name = validated_data.get('company_manager_name', instance.company_manager_name)
            instance.company_address = validated_data.get('company_address', instance.company_address)
            instance.about_company = validated_data.get('about_company', instance.about_company)
            instance.company_website = validated_data.get('company_website', instance.company_website)
            instance.save()

            return instance
        except Exception as e:
            raise e


Views.py

    def put(self, request, pk=None):
        try:
            id1 = pk
            saved_company = Company.objects.get(pk=id1)
            data = request.data
            serializer = CompanyUpdateSerializer(instance=saved_company, data=data)
            if serializer.is_valid():
                serializer.save()
                return self.send_response(success=True, code=f'200', status_code=status.HTTP_200_OK,
                                          description='Company is updated')
            return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                      description=serializer.errors)
        except ObjectDoesNotExist:
            return self.send_response(code='422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                      description="No Company matches the given query.")
        except IntegrityError:
            return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                      description="Email Already Exist")
        except Company.DoesNotExist:
            return self.send_response(code=f'422', status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
                                      description="Company Model doesn't exists")
        except FieldError:
            return self.send_response(code=f'500', description="Cannot resolve keyword given in 'order_by' into field")
        except Exception as e:
            return self.send_response(code=f'500', description=e)


Solution

  • The problem comes from Company.save() method.

    You overrode it as

    class Company(Base):
        ...
    
        def save(self, *args, **kwargs):
            try:
                if not self.pk:
                    self.company_email = self.company_email.replace(" ", "").lower()
                    super().save()
            except Exception:
                raise
    

    Notice the call of super().save() inside the self.pk is None if statement block.

    This will make the actual save method to be called only when the pk is None, meaning that only when a new instance is created, not when an instance is updated.

    Moving the super().save() call to be outside the if statement should handle both creating and updating.

    class Company(Base):
        ...
    
        def save(self, *args, **kwargs):
            try:
                if not self.pk:
                    self.company_email = self.company_email.replace(" ", "").lower()
                super().save(*args, **kwargs)
            except Exception:
                raise