Search code examples
djangopython-3.xdjango-modelsmanytomanyfield

Django models returning updated values in save() and not old values in M2M instance


This is my model

class Userlist(models.Model):
    username = models.CharField(max_length=20)

class Mailinglist(models.Model):
    users = models.ManyToManyField(Userlist, blank=True)

    def __init__(self, *args, **kwargs):
        super(Mailinglist, self).__init__(*args, **kwargs)
        userlist = Userlist.objects.all().filter(mailinglist__id=self.pk)
        setattr(self, '__original_userlist', userlist)

    def log(self):
        userlist = Userlist.objects.filter(mailinglist__id=self.pk)
        original = getattr(self, '__original_userlist')
        print(userlist) #HERE1
        print(original) #HERE2

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        super(Mailinglist, self).save(force_insert, force_update, *args, **kwargs)
        self.log()

I'm trying to get the values before and after the user has been added or removed in my mailinglist, but the values are the same (the new values) in #HERE1 and #HERE2. Any thoughts how I can get the old value?


Solution

  • Ok, I fixed. Django only calls the queries once they are really needed. (Lazy query?)

    What I did was to force the query.

    I made the list as set

    def __init__(self, *args, **kwargs):
        super(Mailinglist, self).__init__(*args, **kwargs)
        userlist = Userlist.objects.all().filter(mailinglist__id=self.pk)
        setattr(self, '__original_userlist', set(userlist))
    

    Then

    def log(self):
        userlist = Userlist.objects.filter(mailinglist__id=self.pk)
        original = getattr(self, '__original_userlist')
        print(set(userlist)) #HERE1
        print(original) #HERE2
    

    This way I could even compare with

    diff = set_original - set_actual