Имитация update_or_create с json-полями и игнорирование элементов, отсутствующих в модели
У меня эта модель:
class SomeModel(models.Model):
field_1 = models.CharField(max_length=200, blank=True, null=True)
field_2 = models.CharField(max_length=200, blank=True, null=True)
и эта функция:
def upload_object_values(model, json_values, keys=None):
model._base_manager.update_or_create(
**{key: json_values[key] for key in keys},
defaults={key: value for key, value in json_values.items() if key not in keys}
)
и назовите его следующим образом:
upload_object_values(SomeModel, { \
'field_1': 'val', \
'field_2': 'val_2'}, \
['field_2'])
это в основном делает:
SomeModel.objects.update_or_create(field_2='val_2')
SomeModel.field_1 = 'val'
SomeModel.save()
Пока все работает правильно. Но он выдает ошибку, если в ключах есть поля или элементы в json не в модели.
например:
upload_object_values(SomeModel, { \
'field_1': 'val', \
'field_2': 'val_2', \
'field_not_in_model': 'val_3'}, \
['field_2', 'field_not_in_model'])
что делает:
SomeModel.objects.update_or_create(field_2='val_2', field_not_in_model='val_3')
SomeModel.field_1 = 'val'
SomeModel.save()
или:
upload_object_values(SomeModel, { \
'field_1': 'val', \
'field_2': 'val_2', \
'field_not_in_model': 'val_3'}, \
['field_2'])
что делает:
SomeModel.objects.update_or_create(field_2='val_2)
SomeModel.field_1 = 'val'
SomeModel.field_not_in_model = 'val_3'
SomeModel.save()
что неверно, поскольку поле не присутствует в модели.
Есть ли способ игнорировать это поле?
для каждого ключа в параметре json_values, который вы передаете в функцию, сначала проверьте, существует ли ключ в списке атрибутов модели, прежде чем присвоить значение модели. например:
def upload_object_values(model, json_values, keys=None):
new_json_values = {}
for key in json_values.keys():
try:
if model._meta.get_field(key):
new_json_values[key] = json_values[key]
except:
pass
model._base_manager.update_or_create(
**{key: new_json_values[key] for key in keys},
defaults={key: value for key, value in
new_json_values.items() if key not in keys}
)
Получение полей модели в Django
или вы также можете сначала проверить ключи, прежде чем передать их в функцию