Assuming you need to check for an existing instance, you can find it with get or create:
instance, created = Book.objects.get_or_create(slug=slug, defaults=d)
if not created:
for attr, value in d.items():
setattr(instance, attr, value)
instance.save()
As mentioned in another answer, you can also use the update function on the queryset manager, but i believe that will not send any signals out (which may not matter to you if you aren't using them). However, you probably shouldn't use it to alter a single object:
Adding on top of other answers, here's a bit more secure version to prevent messing up with related fields:
def is_simple_editable_field(field):
return (
field.editable
and not field.primary_key
and not isinstance(field, (ForeignObjectRel, RelatedField))
)
def update_from_dict(instance, attrs, commit):
allowed_field_names = {
f.name for f in instance._meta.get_fields()
if is_simple_editable_field(f)
}
for attr, val in attrs.items():
if attr in allowed_field_names:
setattr(instance, attr, val)
if commit:
instance.save()
It checks, that field you're trying to update is editable, is not primary key and is not one of related fields.
Example usage:
book = Book.objects.first()
update_from_dict(book, {"num_pages":40, author:"Jack", date:"3324"})
The luxury DRF serializers .create and .update methods have is that there is limited and validated set of fields, which is not the case for manual update.
if you have already Django object and you want to update it's field, you may do it without filter. because you have it already, in this case, yoy may :