django - compare two objects [using fields dynamically] -


i need compare 2 objects, determine if field has changed or not

class country(models.model):  # country code 'mx' -> mexico     code = models.charfield(max_length=2)     name = models.charfield(max_length=15)   class client(models.model): # id=1, name=pedro, country.code=mx, rfc=12345     name = models.charfield(max_length=100)     country = models.foreignkey(country)     rfc = models.charfield(max_length=13)    > obj_db = client.object.get(id=1)  > country = country.objects.get(code='mx') obj_no_db = client(**{'id':1, 'name':'pedro', 'country': country, 'rfc':12345})  > obj_db == obj_no_db # true  > obj_no_db = client(**{'id':1, 'name':'pedro', 'country': country, 'rfc':1})  > obj_db == obj_no_db # true # isn't true because rfc has change, how can compare field field  > obj_db.rfc == obj_no_db.rfc # false expected result 

i need build function generic, problem don't found information it, think can use ._meta options, i'm not sure. developed function can't discover way compare field field.

def get_insert_update(obj, key, obj_list, fields=none, exclude_fields=none):     """      :param obj: object compare     :param key: key compare determine if need update or insert     :param obj_list: list objects compare     :return: to_insert, _update     """     db = {}     to_insert = []     to_update = []     if key == 'pk':  # field pk doesn't exists change id, because same         key = 'id'     exclude_fields = exclude_fields or []     fields = fields or []     if 'pk' in fields:         fields[fields.index('pk')] = 'id'  # change field pk, because doesn't exists     if 'pk' in exclude_fields:         exclude_fields[exclude_fields.index('pk')] = 'id'  # change field pk, because doesn't exists      meta = obj._meta  # define meta object      if fields none:         fields = meta.get_all_field_names()      fields = [f f in meta.fields if f.attname in fields]      # dumping db memory     _obj in obj.objects.all():         if isinstance(key, list):  # first check if list create custom key             _key = _get_key(_obj, key)         else:             _key = _obj.__dict__[key]         # if exclude fields exists         if exclude_fields:             d = {f.attname: _obj.__dict__[f.attname] f in fields if f.attname not in exclude_fields}             db[_key] = obj(**d)         else:  # save full object             db[_key] = _obj     # read local objects determine if record insert or update     _obj in obj_list:         if isinstance(key, list):  # first check if list create custom key             _key = _get_key(_obj, key)         else:             _key = _obj.__dict__[key]         if _key in db:  # if key in db check if equal             # if _obj.pk == 6: # debug             #    print(_obj.__dict__, db[_key].__dict__, _obj.__dict__ == db[_key].__dict__)             if _obj != db[_key]: # here need determine if fields equal or not.                 to_update.append(_obj)  # if object has changed, update             else:                 pass  # if object equal, didn't         else:             to_insert.append(_obj)  # because didn't found database, create     return to_insert, to_update  def _get_key(obj, lst):     """     create string key using multiples keys      example: obj.id -> 1, obj.name -> 'foo'      lst['id', 'name']     :param lst: list of keys     :return: 1_foo     """     k = []     t in lst:         k.append(str(obj.__dict__[t]))     return "_".split(k) 

django's model class defines __eq__ method compare based on value of pk attribute, why models compare equal.

one simple way override method on own model compare value of __dict__, contains instance's values.

there's slight gotcha this, in __dict__ contains hidden _state object compared id, you'd need filter out of comparison.

def __eq__(self, other):      values = [(k,v) k,v in self.__dict__.items() if k != '_state']      other_values = [(k,v) k,v in other.__dict__.items() if k != '_state']      return values == other_values 

Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -