user1165815
user1165815

Reputation: 305

check what field value changed in django model

I parse data from a restful API call using django-rest-framework ModelSerializer. Here is the code:

    url = "API URL HERE"
    r = requests.get(url)
    json = r.json()
    serializer = myModelSerializer(data=json, many=True)
    if serializer.is_valid():
        serializer.save()

Here is the modelSerializer:

class myModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel

MYModel:

class MyModel(models.Model):
   City =  models.NullBooleanField(default=False, null=True)
   Status = models.CharField(max_length=100, null=True)
   stateName = models.CharField(max_length=50)
   marketingName = models.TextField(null=True)
   county = models.CharField(max_length=200, null=True)

My problem is I need to find out what field value changed from the last time I called the restful api and updated data. OR If there is any new records. How do I achieve this?

Upvotes: 0

Views: 2741

Answers (1)

zemekeneng
zemekeneng

Reputation: 1725

First, you could add a column to your MyModel:

updated = models.DateTimeField(auto_now=True)

This will update whenever an instance is changed. If you filter on this field in your queryset, you can determine what rows changed and if there are new rows.

Finding out what field changed is harder, but here is an idea--add a string field to the model and write a custom save method for your model, like this:

class MyModel(models.Model):
    City =  models.NullBooleanField(default=False, null=True)
    Status = models.CharField(max_length=100, null=True)
    stateName = models.CharField(max_length=50)
    marketingName = models.TextField(null=True)
    county = models.CharField(max_length=200, null=True)

    updated = models.DateTimeField(auto_now=True)
    updated_fields = models.CharField(max_length=200, null=True)

    def save(self, *args, **kwargs):
        if not self.pk: # if this is new, just save
            super(MyModel, self).save(*args, **kwargs)
        else:
            # get the original
            old = MyModel.objects.get(id=self.pk)

            # make a list of changed fields
            changed_fields = []
            for field in self._meta.get_all_field_names():
                if getattr(self, field, None) != getattr(old, field, None):
                    if field not in ['updated', 'updated_fields']:
                        changed_fields.append(old)

            # make a comma separated string
            self.updated_fields = ','.join(changed_fields)
            super(MyModel, self).save(*args, **kwargs)

Now the updated_fields column will contain the set of fields that were last updated.

Upvotes: 2

Related Questions