Обратите внимание, что ваше текущее решение:
def my_fancy_update(self, **kwargs):
self.name = kwargs.get('name')
self.house = kwargs.get('house')
self.salary = kwargs.get('salary')
self.save()
очень хрупкое, поскольку оно может установить любое имя, дом и зарплату на None
.
Первое чистое решение будетиспользовать цикл for иладка:
def my_fancy_update(self, **kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
self.save()
, но это все еще хрупко, поскольку он не проверяет, что переданные имена на самом деле являются именами полей модели.Более безопасная реализация будет использовать self._meta.get_fields()
для проверки этого:
def my_fancy_update(self, **kwargs):
fieldnames = set(f.name for f in self._meta.get_fields())
for name, value in kwargs.items():
if name not in fieldnames:
raise ValueError("%s is not a field of %s" % (name, type(self).__name__))
setattr(self, name, value)
self.save()
и, наконец, вы можете избежать вызова save()
, если ничего не было обновлено, и фиксировать только то, что было действительно обновлено:
def my_fancy_update(self, **kwargs):
if not kwargs:
return
fieldnames = set(f.name for f in self._meta.get_fields())
updated = []
for name, value in kwargs.items():
if name not in fieldnames:
raise ValueError("%s is not a field of %s" % (name, type(self).__name__))
setattr(self, name, value)
updated.append(name)
self.save(update_fields=updated)